diff options
author | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:28:10 -0700 |
---|---|---|
committer | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:41:56 -0700 |
commit | 3f3b45cc74b0499912409f766a595945dbbfc4c5 (patch) | |
tree | ec400b6965477b88ea7f0d335f7e5c52044c346c /core/src/fpdfapi/fpdf_page | |
parent | 6fe4aed948337175f6f7f81bb03c37b9c7f535da (diff) | |
download | pdfium-3f3b45cc74b0499912409f766a595945dbbfc4c5.tar.xz |
Convert all line endings to LF.
Diffstat (limited to 'core/src/fpdfapi/fpdf_page')
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page.cpp | 2094 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp | 2802 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 1294 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp | 1772 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp | 1414 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_image.cpp | 232 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 3362 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser_new.cpp | 1644 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp | 2292 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_path.cpp | 104 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp | 556 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/pageint.h | 1010 |
12 files changed, 9288 insertions, 9288 deletions
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp index 232e5619a7..3cfb93e4bc 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp @@ -1,1047 +1,1047 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "pageint.h"
-void CPDF_PageObject::Release()
-{
- delete this;
-}
-CPDF_PageObject* CPDF_PageObject::Create(int type)
-{
- switch (type) {
- case PDFPAGE_TEXT:
- return FX_NEW CPDF_TextObject;
- case PDFPAGE_IMAGE:
- return FX_NEW CPDF_ImageObject;
- case PDFPAGE_PATH:
- return FX_NEW CPDF_PathObject;
- case PDFPAGE_SHADING:
- return FX_NEW CPDF_ShadingObject;
- case PDFPAGE_FORM:
- return FX_NEW CPDF_FormObject;
- }
- return NULL;
-}
-CPDF_PageObject* CPDF_PageObject::Clone() const
-{
- CPDF_PageObject* pObj = Create(m_Type);
- pObj->Copy(this);
- return pObj;
-}
-void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc)
-{
- if (m_Type != pSrc->m_Type) {
- return;
- }
- CopyData(pSrc);
- CopyStates(*pSrc);
- m_Left = pSrc->m_Left;
- m_Right = pSrc->m_Right;
- m_Top = pSrc->m_Top;
- m_Bottom = pSrc->m_Bottom;
-}
-void CPDF_PageObject::AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge)
-{
- m_ClipPath.AppendPath(path, type, bAutoMerge);
-}
-void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj)
-{
- m_ClipPath = pObj->m_ClipPath;
-}
-void CPDF_PageObject::RemoveClipPath()
-{
- m_ClipPath.SetNull();
-}
-void CPDF_PageObject::RecalcBBox()
-{
- switch (m_Type) {
- case PDFPAGE_TEXT:
- ((CPDF_TextObject*)this)->RecalcPositionData();
- break;
- case PDFPAGE_PATH:
- ((CPDF_PathObject*)this)->CalcBoundingBox();
- break;
- case PDFPAGE_SHADING:
- ((CPDF_ShadingObject*)this)->CalcBoundingBox();
- break;
- }
-}
-void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix)
-{
- if (m_ClipPath.IsNull()) {
- return;
- }
- m_ClipPath.GetModify();
- m_ClipPath.Transform(matrix);
-}
-void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix)
-{
- if(m_GeneralState.IsNull()) {
- return;
- }
- CPDF_GeneralStateData* pGS = m_GeneralState.GetModify();
- pGS->m_Matrix.Concat(matrix);
-}
-FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const
-{
- CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top);
- if (pMatrix) {
- pMatrix->TransformRect(rect);
- }
- return rect.GetOutterRect();
-}
-CPDF_TextObject::CPDF_TextObject()
-{
- m_Type = PDFPAGE_TEXT;
- m_pCharCodes = NULL;
- m_pCharPos = NULL;
- m_nChars = 0;
- m_PosX = m_PosY = 0;
-}
-CPDF_TextObject::~CPDF_TextObject()
-{
- if (m_nChars > 1 && m_pCharCodes) {
- FX_Free(m_pCharCodes);
- }
- if (m_pCharPos) {
- FX_Free(m_pCharPos);
- }
-}
-void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const
-{
- pInfo->m_CharCode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[index];
- pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0;
- pInfo->m_OriginY = 0;
- if (pInfo->m_CharCode == -1) {
- return;
- }
- CPDF_Font* pFont = m_TextState.GetFont();
- if (pFont->GetFontType() != PDFFONT_CIDFONT) {
- return;
- }
- if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) {
- return;
- }
- FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode);
- pInfo->m_OriginY = pInfo->m_OriginX;
- pInfo->m_OriginX = 0;
- short vx, vy;
- ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy);
- FX_FLOAT fontsize = m_TextState.GetFontSize();
- pInfo->m_OriginX -= fontsize * vx / 1000;
- pInfo->m_OriginY -= fontsize * vy / 1000;
-}
-int CPDF_TextObject::CountChars() const
-{
- if (m_nChars == 1) {
- return 1;
- }
- int count = 0;
- for (int i = 0; i < m_nChars; i ++)
- if (m_pCharCodes[i] != (FX_DWORD) - 1) {
- count ++;
- }
- return count;
-}
-void CPDF_TextObject::GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const
-{
- if (m_nChars == 1) {
- charcode = (FX_DWORD)(FX_UINTPTR)m_pCharCodes;
- kerning = 0;
- return;
- }
- int count = 0;
- for (int i = 0; i < m_nChars; i ++) {
- if (m_pCharCodes[i] != (FX_DWORD) - 1) {
- if (count == index) {
- charcode = m_pCharCodes[i];
- if (i == m_nChars - 1 || m_pCharCodes[i + 1] != (FX_DWORD) - 1) {
- kerning = 0;
- } else {
- kerning = m_pCharPos[i];
- }
- return;
- }
- count ++;
- }
- }
-}
-void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const
-{
- if (m_nChars == 1) {
- GetItemInfo(0, pInfo);
- return;
- }
- int count = 0;
- for (int i = 0; i < m_nChars; i ++) {
- FX_DWORD charcode = m_pCharCodes[i];
- if (charcode == (FX_DWORD) - 1) {
- continue;
- }
- if (count == index) {
- GetItemInfo(i, pInfo);
- break;
- }
- count ++;
- }
-}
-void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc)
-{
- const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc;
- if (m_nChars > 1 && m_pCharCodes) {
- FX_Free(m_pCharCodes);
- m_pCharCodes = NULL;
- }
- if (m_pCharPos) {
- FX_Free(m_pCharPos);
- m_pCharPos = NULL;
- }
- m_nChars = pSrcObj->m_nChars;
- if (m_nChars > 1) {
- m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
- m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
- int i;
- for (i = 0; i < m_nChars; i ++) {
- m_pCharCodes[i] = pSrcObj->m_pCharCodes[i];
- }
- for (i = 0; i < m_nChars - 1; i ++) {
- m_pCharPos[i] = pSrcObj->m_pCharPos[i];
- }
- } else {
- m_pCharCodes = pSrcObj->m_pCharCodes;
- }
- m_PosX = pSrcObj->m_PosX;
- m_PosY = pSrcObj->m_PosY;
-}
-void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const
-{
- FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
- pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], m_PosX, m_PosY);
-}
-void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nsegs)
-{
- if (m_nChars > 1 && m_pCharCodes) {
- FX_Free(m_pCharCodes);
- m_pCharCodes = NULL;
- }
- if (m_pCharPos) {
- FX_Free(m_pCharPos);
- m_pCharPos = NULL;
- }
- CPDF_Font* pFont = m_TextState.GetFont();
- m_nChars = 0;
- for (int i = 0; i < nsegs; i ++) {
- m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength());
- }
- m_nChars += nsegs - 1;
- if (m_nChars > 1) {
- m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
- m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
- int index = 0;
- for (int i = 0; i < nsegs; i ++) {
- FX_LPCSTR segment = pStrs[i];
- int offset = 0, len = pStrs[i].GetLength();
- while (offset < len) {
- m_pCharCodes[index++] = pFont->GetNextChar(segment, offset);
- }
- if (i != nsegs - 1) {
- m_pCharPos[index - 1] = pKerning[i];
- m_pCharCodes[index ++] = (FX_DWORD) - 1;
- }
- }
- } else {
- int offset = 0;
- m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pFont->GetNextChar(pStrs[0], offset);
- }
-}
-void CPDF_TextObject::SetText(const CFX_ByteString& str)
-{
- SetSegments(&str, NULL, 1);
- RecalcPositionData();
-}
-void CPDF_TextObject::SetEmpty()
-{
- if (m_nChars > 1 && m_pCharCodes) {
- FX_Free(m_pCharCodes);
- }
- if (m_nChars > 1 && m_pCharPos) {
- FX_Free(m_pCharPos);
- }
- m_nChars = 0;
- m_pCharCodes = NULL;
- m_pCharPos = NULL;
- m_Left = m_Right = m_PosX;
- m_Top = m_Bottom = m_PosY;
-}
-void CPDF_TextObject::SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs)
-{
- SetSegments(pStrs, pKerning, nSegs);
- RecalcPositionData();
-}
-void CPDF_TextObject::SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings)
-{
- if (m_nChars > 1 && m_pCharCodes) {
- FX_Free(m_pCharCodes);
- m_pCharCodes = NULL;
- }
- if (m_pCharPos) {
- FX_Free(m_pCharPos);
- m_pCharPos = NULL;
- }
- int nKernings = 0;
- int i;
- for (i = 0; i < nChars - 1; i ++)
- if (pKernings[i] != 0) {
- nKernings ++;
- }
- m_nChars = nChars + nKernings;
- if (m_nChars > 1) {
- m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
- m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
- int index = 0;
- for (int i = 0; i < nChars; i ++) {
- m_pCharCodes[index++] = pCharCodes[i];
- if (pKernings[i] != 0 && i != nChars - 1) {
- m_pCharCodes[index] = (FX_DWORD) - 1;
- m_pCharPos[index - 1] = pKernings[i];
- index ++;
- }
- }
- } else {
- int offset = 0;
- m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pCharCodes[0];
- }
- RecalcPositionData();
-}
-FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const
-{
- FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
- CPDF_Font* pFont = m_TextState.GetFont();
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- }
- if (!bVertWriting) {
- return pFont->GetCharWidthF(charcode, 0) * fontsize;
- } else {
- FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
- return pCIDFont->GetVertWidth(CID) * fontsize;
- }
-}
-FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const
-{
- CPDF_Font* pFont = m_TextState.GetFont();
- FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32);
- if (charCode != (FX_DWORD) - 1) {
- return GetCharWidth(charCode);
- }
- FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f;
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- }
- FX_RECT fontRect;
- pFont->GetFontBBox(fontRect);
- fontSize *= bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width();
- return fontSize;
-}
-void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const
-{
- FX_FLOAT curpos = 0;
- CPDF_Font* pFont = m_TextState.GetFont();
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- }
- FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
- int count = 0;
- for (int i = 0; i < m_nChars; i ++) {
- FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
- if (charcode == (FX_DWORD) - 1) {
- continue;
- }
- if( count != index) {
- count++;
- continue;
- }
- FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0;
- FX_RECT char_rect;
- pFont->GetCharBBox(charcode, char_rect, 0);
- if (!bVertWriting) {
- rect.left = curpos + char_rect.left * fontsize;
- rect.right = curpos + char_rect.right * fontsize;
- rect.top = char_rect.top * fontsize;
- rect.bottom = char_rect.bottom * fontsize;
- } else {
- FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
- short vx, vy;
- pCIDFont->GetVertOrigin(CID, vx, vy);
- char_rect.left -= vx;
- char_rect.right -= vx;
- char_rect.top -= vy;
- char_rect.bottom -= vy;
- rect.left = char_rect.left * fontsize;
- rect.right = char_rect.right * fontsize;
- rect.top = curpos + char_rect.top * fontsize;
- rect.bottom = curpos + char_rect.bottom * fontsize;
- }
- return;
- }
-}
-void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, FX_FLOAT horz_scale, int level)
-{
- FX_FLOAT curpos = 0;
- FX_FLOAT min_x = 10000 * 1.0f, max_x = -10000 * 1.0f, min_y = 10000 * 1.0f, max_y = -10000 * 1.0f;
- CPDF_Font* pFont = m_TextState.GetFont();
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- }
- FX_FLOAT fontsize = m_TextState.GetFontSize();
- for (int i = 0; i < m_nChars; i ++) {
- FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
- if (charcode == (FX_DWORD) - 1) {
- curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
- continue;
- }
- if (i) {
- m_pCharPos[i - 1] = curpos;
- }
- FX_RECT char_rect;
- pFont->GetCharBBox(charcode, char_rect, level);
- FX_FLOAT charwidth;
- if (!bVertWriting) {
- if (min_y > char_rect.top) {
- min_y = (FX_FLOAT)char_rect.top;
- }
- if (max_y < char_rect.top) {
- max_y = (FX_FLOAT)char_rect.top;
- }
- if (min_y > char_rect.bottom) {
- min_y = (FX_FLOAT)char_rect.bottom;
- }
- if (max_y < char_rect.bottom) {
- max_y = (FX_FLOAT)char_rect.bottom;
- }
- FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
- FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
- if (min_x > char_left) {
- min_x = char_left;
- }
- if (max_x < char_left) {
- max_x = char_left;
- }
- if (min_x > char_right) {
- min_x = char_right;
- }
- if (max_x < char_right) {
- max_x = char_right;
- }
- charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
- } else {
- FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
- short vx, vy;
- pCIDFont->GetVertOrigin(CID, vx, vy);
- char_rect.left -= vx;
- char_rect.right -= vx;
- char_rect.top -= vy;
- char_rect.bottom -= vy;
- if (min_x > char_rect.left) {
- min_x = (FX_FLOAT)char_rect.left;
- }
- if (max_x < char_rect.left) {
- max_x = (FX_FLOAT)char_rect.left;
- }
- if (min_x > char_rect.right) {
- min_x = (FX_FLOAT)char_rect.right;
- }
- if (max_x < char_rect.right) {
- max_x = (FX_FLOAT)char_rect.right;
- }
- FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
- FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
- if (min_y > char_top) {
- min_y = char_top;
- }
- if (max_y < char_top) {
- max_y = char_top;
- }
- if (min_y > char_bottom) {
- min_y = char_bottom;
- }
- if (max_y < char_bottom) {
- max_y = char_bottom;
- }
- charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
- }
- curpos += charwidth;
- if (charcode == ' ' && (pCIDFont == NULL || pCIDFont->GetCharSize(32) == 1)) {
- curpos += m_TextState.GetObject()->m_WordSpace;
- }
- curpos += m_TextState.GetObject()->m_CharSpace;
- }
- if (bVertWriting) {
- if (pTextAdvanceX) {
- *pTextAdvanceX = 0;
- }
- if (pTextAdvanceY) {
- *pTextAdvanceY = curpos;
- }
- min_x = min_x * fontsize / 1000;
- max_x = max_x * fontsize / 1000;
- } else {
- if (pTextAdvanceX) {
- *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
- }
- if (pTextAdvanceY) {
- *pTextAdvanceY = 0;
- }
- min_y = min_y * fontsize / 1000;
- max_y = max_y * fontsize / 1000;
- }
- CFX_AffineMatrix matrix;
- GetTextMatrix(&matrix);
- m_Left = min_x;
- m_Right = max_x;
- m_Bottom = min_y;
- m_Top = max_y;
- matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
- int textmode = m_TextState.GetObject()->m_TextMode;
- if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
- FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
- m_Left -= half_width;
- m_Right += half_width;
- m_Top += half_width;
- m_Bottom -= half_width;
- }
-}
-void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const
-{
- FX_FLOAT curpos = 0;
- int count = 0;
- CPDF_Font* pFont = m_TextState.GetFont();
- FX_BOOL bVertWriting = FALSE;
- CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- }
- FX_FLOAT fontsize = m_TextState.GetFontSize();
- int index = 0;
- for (int i = 0; i < m_nChars; i ++) {
- FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
- if (charcode == (FX_DWORD) - 1) {
- continue;
- }
- pPosArray[index++] = i ? m_pCharPos[i - 1] : 0;
- FX_FLOAT charwidth;
- if (bVertWriting) {
- FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
- charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
- } else {
- charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000;
- }
- pPosArray[index] = pPosArray[index - 1] + charwidth;
- index++;
- }
-}
-void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix)
-{
- m_TextState.GetModify();
- CFX_AffineMatrix text_matrix;
- GetTextMatrix(&text_matrix);
- text_matrix.Concat(matrix);
- FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
- pTextMatrix[0] = text_matrix.GetA();
- pTextMatrix[1] = text_matrix.GetC();
- pTextMatrix[2] = text_matrix.GetB();
- pTextMatrix[3] = text_matrix.GetD();
- m_PosX = text_matrix.GetE();
- m_PosY = text_matrix.GetF();
- CalcPositionData(NULL, NULL, 0);
-}
-void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y)
-{
- FX_FLOAT dx = x - m_PosX;
- FX_FLOAT dy = y - m_PosY;
- m_PosX = x;
- m_PosY = y;
- m_Left += dx;
- m_Right += dx;
- m_Top += dy;
- m_Bottom += dy;
-}
-void CPDF_TextObject::SetData(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, FX_FLOAT x, FX_FLOAT y)
-{
- ASSERT(m_nChars == 0);
- m_nChars = nChars;
- m_PosX = x;
- m_PosY = y;
- if (nChars == 0) {
- return;
- }
- if (nChars == 1) {
- m_pCharCodes = (FX_DWORD*)(FX_UINTPTR) * pCharCodes;
- } else {
- m_pCharCodes = FX_Alloc(FX_DWORD, nChars);
- FXSYS_memcpy32(m_pCharCodes, pCharCodes, sizeof(FX_DWORD)*nChars);
- m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1);
- FXSYS_memcpy32(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1));
- }
- RecalcPositionData();
-}
-void CPDF_TextObject::SetTextState(CPDF_TextState TextState)
-{
- m_TextState = TextState;
- CalcPositionData(NULL, NULL, 0);
-}
-CPDF_ShadingObject::CPDF_ShadingObject()
-{
- m_pShading = NULL;
- m_Type = PDFPAGE_SHADING;
-}
-CPDF_ShadingObject::~CPDF_ShadingObject()
-{
- CPDF_ShadingPattern* pShading = m_pShading;
- if (pShading && pShading->m_pDocument) {
- pShading->m_pDocument->GetPageData()->ReleasePattern(pShading->m_pShadingObj);
- }
-}
-void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc)
-{
- CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc;
- m_pShading = pSrcObj->m_pShading;
- if (m_pShading && m_pShading->m_pDocument) {
- CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData();
- m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(m_pShading->m_pShadingObj, m_pShading->m_bShadingObj, &m_pShading->m_ParentMatrix);
- }
- m_Matrix = pSrcObj->m_Matrix;
-}
-void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix)
-{
- if (!m_ClipPath.IsNull()) {
- m_ClipPath.GetModify();
- m_ClipPath.Transform(matrix);
- }
- m_Matrix.Concat(matrix);
- if (!m_ClipPath.IsNull()) {
- CalcBoundingBox();
- } else {
- matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
- }
-}
-void CPDF_ShadingObject::CalcBoundingBox()
-{
- if (m_ClipPath.IsNull()) {
- return;
- }
- CFX_FloatRect rect = m_ClipPath.GetClipBox();
- m_Left = rect.left;
- m_Bottom = rect.bottom;
- m_Right = rect.right;
- m_Top = rect.top;
-}
-CPDF_FormObject::~CPDF_FormObject()
-{
- if (m_pForm) {
- delete m_pForm;
- }
-}
-void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix)
-{
- m_FormMatrix.Concat(matrix);
- CalcBoundingBox();
-}
-void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc)
-{
- const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc;
- if (m_pForm) {
- delete m_pForm;
- }
- m_pForm = pSrcObj->m_pForm->Clone();
- m_FormMatrix = pSrcObj->m_FormMatrix;
-}
-void CPDF_FormObject::CalcBoundingBox()
-{
- CFX_FloatRect form_rect = m_pForm->CalcBoundingBox();
- form_rect.Transform(&m_FormMatrix);
- m_Left = form_rect.left;
- m_Bottom = form_rect.bottom;
- m_Right = form_rect.right;
- m_Top = form_rect.top;
-}
-CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) : m_ObjectList(128)
-{
- m_bBackgroundAlphaNeeded = FALSE;
- m_bReleaseMembers = bReleaseMembers;
- m_ParseState = PDF_CONTENT_NOT_PARSED;
- m_pParser = NULL;
- m_pFormStream = NULL;
- m_pResources = NULL;
-}
-CPDF_PageObjects::~CPDF_PageObjects()
-{
- if (m_pParser) {
- delete m_pParser;
- }
- if (!m_bReleaseMembers) {
- return;
- }
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- if (!pPageObj) {
- continue;
- }
- pPageObj->Release();
- }
-}
-void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause)
-{
- if (m_pParser == NULL) {
- return;
- }
- m_pParser->Continue(pPause);
- if (m_pParser->GetStatus() == CPDF_ContentParser::Done) {
- m_ParseState = PDF_CONTENT_PARSED;
- delete m_pParser;
- m_pParser = NULL;
- }
-}
-int CPDF_PageObjects::EstimateParseProgress() const
-{
- if (m_pParser == NULL) {
- return m_ParseState == PDF_CONTENT_PARSED ? 100 : 0;
- }
- return m_pParser->EstimateProgress();
-}
-FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, CPDF_PageObject* pNewObject)
-{
- if (posInsertAfter == NULL) {
- return m_ObjectList.AddHead(pNewObject);
- } else {
- return m_ObjectList.InsertAfter(posInsertAfter, pNewObject);
- }
-}
-int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const
-{
- int index = 0;
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- if (pThisObj == pObj) {
- return index;
- }
- index ++;
- }
- return -1;
-}
-CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const
-{
- FX_POSITION pos = m_ObjectList.FindIndex(index);
- if (pos == NULL) {
- return NULL;
- }
- return (CPDF_PageObject*)m_ObjectList.GetAt(pos);
-}
-void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix)
-{
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- pObj->Transform(matrix);
- }
-}
-CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const
-{
- if (m_ObjectList.GetCount() == 0) {
- return CFX_FloatRect(0, 0, 0, 0);
- }
- FX_FLOAT left, right, top, bottom;
- left = bottom = 1000000 * 1.0f;
- right = top = -1000000 * 1.0f;
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- if (left > pObj->m_Left) {
- left = pObj->m_Left;
- }
- if (right < pObj->m_Right) {
- right = pObj->m_Right;
- }
- if (top < pObj->m_Top) {
- top = pObj->m_Top;
- }
- if (bottom > pObj->m_Bottom) {
- bottom = pObj->m_Bottom;
- }
- }
- return CFX_FloatRect(left, bottom, right, top);
-}
-void CPDF_PageObjects::LoadTransInfo()
-{
- if (m_pFormDict == NULL) {
- return;
- }
- CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group"));
- if (pGroup == NULL) {
- return;
- }
- if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) {
- return;
- }
- m_Transparency |= PDFTRANS_GROUP;
- if (pGroup->GetInteger(FX_BSTRC("I"))) {
- m_Transparency |= PDFTRANS_ISOLATED;
- }
- if (pGroup->GetInteger(FX_BSTRC("K"))) {
- m_Transparency |= PDFTRANS_KNOCKOUT;
- }
-}
-void CPDF_PageObjects::ClearCacheObjects()
-{
- m_ParseState = PDF_CONTENT_NOT_PARSED;
- if (m_pParser) {
- delete m_pParser;
- }
- m_pParser = NULL;
- if (m_bReleaseMembers) {
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- if (!pPageObj) {
- continue;
- }
- pPageObj->Release();
- }
- }
- m_ObjectList.RemoveAll();
-}
-CPDF_Page::CPDF_Page()
-{
- m_pPageRender = NULL;
-}
-void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BOOL bPageCache)
-{
- m_pDocument = (CPDF_Document*)pDocument;
- m_pFormDict = pPageDict;
- if (bPageCache) {
- m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this);
- }
- if (pPageDict == NULL) {
- m_PageWidth = m_PageHeight = 100 * 1.0f;
- m_pPageResources = m_pResources = NULL;
- return;
- }
- m_pResources = GetPageAttr(FX_BSTRC("Resources"))->GetDict();
- m_pPageResources = m_pResources;
- CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate"));
- int rotate = 0;
- if (pRotate) {
- rotate = pRotate->GetInteger() / 90 % 4;
- }
- if (rotate < 0) {
- rotate += 4;
- }
- CPDF_Array* pMediaBox, *pCropBox;
- pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox"));
- CFX_FloatRect mediabox;
- if (pMediaBox) {
- mediabox = pMediaBox->GetRect();
- mediabox.Normalize();
- }
- if (mediabox.IsEmpty()) {
- mediabox = CFX_FloatRect(0, 0, 612, 792);
- }
- pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox"));
- if (pCropBox) {
- m_BBox = pCropBox->GetRect();
- m_BBox.Normalize();
- }
- if (m_BBox.IsEmpty()) {
- m_BBox = mediabox;
- } else {
- m_BBox.Intersect(mediabox);
- }
- if (rotate % 2) {
- m_PageHeight = m_BBox.right - m_BBox.left;
- m_PageWidth = m_BBox.top - m_BBox.bottom;
- } else {
- m_PageWidth = m_BBox.right - m_BBox.left;
- m_PageHeight = m_BBox.top - m_BBox.bottom;
- }
- switch (rotate) {
- case 0:
- m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom);
- break;
- case 1:
- m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right);
- break;
- case 2:
- m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top);
- break;
- case 3:
- m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left);
- break;
- }
- m_Transparency = PDFTRANS_ISOLATED;
- LoadTransInfo();
-}
-void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
-{
- if (bReParse) {
- ClearCacheObjects();
- }
- if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
- return;
- }
- m_pParser = FX_NEW CPDF_ContentParser;
- m_pParser->Start(this, pOptions);
- m_ParseState = PDF_CONTENT_PARSING;
-}
-void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
-{
- StartParse(pOptions, bReParse);
- ContinueParse(NULL);
-}
-CPDF_Page::~CPDF_Page()
-{
- if (m_pPageRender) {
- CPDF_RenderModuleDef* pModule = CPDF_ModuleMgr::Get()->GetRenderModule();
- pModule->DestroyPageCache(m_pPageRender);
- }
-}
-CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, FX_BSTR name)
-{
- int level = 0;
- while (1) {
- CPDF_Object* pObj = pPageDict->GetElementValue(name);
- if (pObj) {
- return pObj;
- }
- CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent"));
- if (!pParent || pParent == pPageDict) {
- return NULL;
- }
- pPageDict = pParent;
- level ++;
- if (level == 1000) {
- return NULL;
- }
- }
-}
-CPDF_Object* CPDF_Page::GetPageAttr(FX_BSTR name) const
-{
- return FPDFAPI_GetPageAttr(m_pFormDict, name);
-}
-CPDF_Form::CPDF_Form(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Stream* pFormStream, CPDF_Dictionary* pParentResources)
-{
- m_pDocument = pDoc;
- m_pFormStream = pFormStream;
- m_pFormDict = pFormStream->GetDict();
- m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources"));
- m_pPageResources = pPageResources;
- if (m_pResources == NULL) {
- m_pResources = pParentResources;
- }
- if (m_pResources == NULL) {
- m_pResources = pPageResources;
- }
- m_Transparency = 0;
- LoadTransInfo();
-}
-CPDF_Form::~CPDF_Form()
-{
-}
-void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
- CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
-{
- if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
- return;
- }
- m_pParser = FX_NEW CPDF_ContentParser;
- m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
- m_ParseState = PDF_CONTENT_PARSING;
-}
-void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
- CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
-{
- StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
- ContinueParse(NULL);
-}
-CPDF_Form* CPDF_Form::Clone() const
-{
- CPDF_Form* pClone = FX_NEW CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources);
- FX_POSITION pos = m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
- pClone->m_ObjectList.AddTail(pObj->Clone());
- }
- return pClone;
-}
-void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos,
- int xSize, int ySize, int iRotate) const
-{
- if (m_PageWidth == 0 || m_PageHeight == 0) {
- return;
- }
- CFX_AffineMatrix display_matrix;
- int x0, y0, x1, y1, x2, y2;
- iRotate %= 4;
- switch (iRotate) {
- case 0:
- x0 = xPos;
- y0 = yPos + ySize;
- x1 = xPos;
- y1 = yPos;
- x2 = xPos + xSize;
- y2 = yPos + ySize;
- break;
- case 1:
- x0 = xPos;
- y0 = yPos;
- x1 = xPos + xSize;
- y1 = yPos;
- x2 = xPos;
- y2 = yPos + ySize;
- break;
- case 2:
- x0 = xPos + xSize;
- y0 = yPos;
- x1 = xPos + xSize;
- y1 = yPos + ySize;
- x2 = xPos;
- y2 = yPos;
- break;
- case 3:
- x0 = xPos + xSize;
- y0 = yPos + ySize;
- x1 = xPos;
- y1 = yPos + ySize;
- x2 = xPos + xSize;
- y2 = yPos;
- break;
- }
- display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth),
- FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth),
- FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight),
- FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight),
- (FX_FLOAT)x0, (FX_FLOAT)y0);
- matrix = m_PageMatrix;
- matrix.Concat(display_matrix);
-}
-CPDF_ParseOptions::CPDF_ParseOptions()
-{
- m_bTextOnly = FALSE;
- m_bMarkedContent = TRUE;
- m_bSeparateForm = TRUE;
- m_bDecodeInlineImage = FALSE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "pageint.h" +void CPDF_PageObject::Release() +{ + delete this; +} +CPDF_PageObject* CPDF_PageObject::Create(int type) +{ + switch (type) { + case PDFPAGE_TEXT: + return FX_NEW CPDF_TextObject; + case PDFPAGE_IMAGE: + return FX_NEW CPDF_ImageObject; + case PDFPAGE_PATH: + return FX_NEW CPDF_PathObject; + case PDFPAGE_SHADING: + return FX_NEW CPDF_ShadingObject; + case PDFPAGE_FORM: + return FX_NEW CPDF_FormObject; + } + return NULL; +} +CPDF_PageObject* CPDF_PageObject::Clone() const +{ + CPDF_PageObject* pObj = Create(m_Type); + pObj->Copy(this); + return pObj; +} +void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc) +{ + if (m_Type != pSrc->m_Type) { + return; + } + CopyData(pSrc); + CopyStates(*pSrc); + m_Left = pSrc->m_Left; + m_Right = pSrc->m_Right; + m_Top = pSrc->m_Top; + m_Bottom = pSrc->m_Bottom; +} +void CPDF_PageObject::AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) +{ + m_ClipPath.AppendPath(path, type, bAutoMerge); +} +void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj) +{ + m_ClipPath = pObj->m_ClipPath; +} +void CPDF_PageObject::RemoveClipPath() +{ + m_ClipPath.SetNull(); +} +void CPDF_PageObject::RecalcBBox() +{ + switch (m_Type) { + case PDFPAGE_TEXT: + ((CPDF_TextObject*)this)->RecalcPositionData(); + break; + case PDFPAGE_PATH: + ((CPDF_PathObject*)this)->CalcBoundingBox(); + break; + case PDFPAGE_SHADING: + ((CPDF_ShadingObject*)this)->CalcBoundingBox(); + break; + } +} +void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix) +{ + if (m_ClipPath.IsNull()) { + return; + } + m_ClipPath.GetModify(); + m_ClipPath.Transform(matrix); +} +void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix) +{ + if(m_GeneralState.IsNull()) { + return; + } + CPDF_GeneralStateData* pGS = m_GeneralState.GetModify(); + pGS->m_Matrix.Concat(matrix); +} +FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const +{ + CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top); + if (pMatrix) { + pMatrix->TransformRect(rect); + } + return rect.GetOutterRect(); +} +CPDF_TextObject::CPDF_TextObject() +{ + m_Type = PDFPAGE_TEXT; + m_pCharCodes = NULL; + m_pCharPos = NULL; + m_nChars = 0; + m_PosX = m_PosY = 0; +} +CPDF_TextObject::~CPDF_TextObject() +{ + if (m_nChars > 1 && m_pCharCodes) { + FX_Free(m_pCharCodes); + } + if (m_pCharPos) { + FX_Free(m_pCharPos); + } +} +void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const +{ + pInfo->m_CharCode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[index]; + pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; + pInfo->m_OriginY = 0; + if (pInfo->m_CharCode == -1) { + return; + } + CPDF_Font* pFont = m_TextState.GetFont(); + if (pFont->GetFontType() != PDFFONT_CIDFONT) { + return; + } + if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) { + return; + } + FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode); + pInfo->m_OriginY = pInfo->m_OriginX; + pInfo->m_OriginX = 0; + short vx, vy; + ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy); + FX_FLOAT fontsize = m_TextState.GetFontSize(); + pInfo->m_OriginX -= fontsize * vx / 1000; + pInfo->m_OriginY -= fontsize * vy / 1000; +} +int CPDF_TextObject::CountChars() const +{ + if (m_nChars == 1) { + return 1; + } + int count = 0; + for (int i = 0; i < m_nChars; i ++) + if (m_pCharCodes[i] != (FX_DWORD) - 1) { + count ++; + } + return count; +} +void CPDF_TextObject::GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const +{ + if (m_nChars == 1) { + charcode = (FX_DWORD)(FX_UINTPTR)m_pCharCodes; + kerning = 0; + return; + } + int count = 0; + for (int i = 0; i < m_nChars; i ++) { + if (m_pCharCodes[i] != (FX_DWORD) - 1) { + if (count == index) { + charcode = m_pCharCodes[i]; + if (i == m_nChars - 1 || m_pCharCodes[i + 1] != (FX_DWORD) - 1) { + kerning = 0; + } else { + kerning = m_pCharPos[i]; + } + return; + } + count ++; + } + } +} +void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const +{ + if (m_nChars == 1) { + GetItemInfo(0, pInfo); + return; + } + int count = 0; + for (int i = 0; i < m_nChars; i ++) { + FX_DWORD charcode = m_pCharCodes[i]; + if (charcode == (FX_DWORD) - 1) { + continue; + } + if (count == index) { + GetItemInfo(i, pInfo); + break; + } + count ++; + } +} +void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc) +{ + const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc; + if (m_nChars > 1 && m_pCharCodes) { + FX_Free(m_pCharCodes); + m_pCharCodes = NULL; + } + if (m_pCharPos) { + FX_Free(m_pCharPos); + m_pCharPos = NULL; + } + m_nChars = pSrcObj->m_nChars; + if (m_nChars > 1) { + m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); + m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); + int i; + for (i = 0; i < m_nChars; i ++) { + m_pCharCodes[i] = pSrcObj->m_pCharCodes[i]; + } + for (i = 0; i < m_nChars - 1; i ++) { + m_pCharPos[i] = pSrcObj->m_pCharPos[i]; + } + } else { + m_pCharCodes = pSrcObj->m_pCharCodes; + } + m_PosX = pSrcObj->m_PosX; + m_PosY = pSrcObj->m_PosY; +} +void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const +{ + FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); + pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], m_PosX, m_PosY); +} +void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nsegs) +{ + if (m_nChars > 1 && m_pCharCodes) { + FX_Free(m_pCharCodes); + m_pCharCodes = NULL; + } + if (m_pCharPos) { + FX_Free(m_pCharPos); + m_pCharPos = NULL; + } + CPDF_Font* pFont = m_TextState.GetFont(); + m_nChars = 0; + for (int i = 0; i < nsegs; i ++) { + m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength()); + } + m_nChars += nsegs - 1; + if (m_nChars > 1) { + m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); + m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); + int index = 0; + for (int i = 0; i < nsegs; i ++) { + FX_LPCSTR segment = pStrs[i]; + int offset = 0, len = pStrs[i].GetLength(); + while (offset < len) { + m_pCharCodes[index++] = pFont->GetNextChar(segment, offset); + } + if (i != nsegs - 1) { + m_pCharPos[index - 1] = pKerning[i]; + m_pCharCodes[index ++] = (FX_DWORD) - 1; + } + } + } else { + int offset = 0; + m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pFont->GetNextChar(pStrs[0], offset); + } +} +void CPDF_TextObject::SetText(const CFX_ByteString& str) +{ + SetSegments(&str, NULL, 1); + RecalcPositionData(); +} +void CPDF_TextObject::SetEmpty() +{ + if (m_nChars > 1 && m_pCharCodes) { + FX_Free(m_pCharCodes); + } + if (m_nChars > 1 && m_pCharPos) { + FX_Free(m_pCharPos); + } + m_nChars = 0; + m_pCharCodes = NULL; + m_pCharPos = NULL; + m_Left = m_Right = m_PosX; + m_Top = m_Bottom = m_PosY; +} +void CPDF_TextObject::SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs) +{ + SetSegments(pStrs, pKerning, nSegs); + RecalcPositionData(); +} +void CPDF_TextObject::SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings) +{ + if (m_nChars > 1 && m_pCharCodes) { + FX_Free(m_pCharCodes); + m_pCharCodes = NULL; + } + if (m_pCharPos) { + FX_Free(m_pCharPos); + m_pCharPos = NULL; + } + int nKernings = 0; + int i; + for (i = 0; i < nChars - 1; i ++) + if (pKernings[i] != 0) { + nKernings ++; + } + m_nChars = nChars + nKernings; + if (m_nChars > 1) { + m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars); + m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); + int index = 0; + for (int i = 0; i < nChars; i ++) { + m_pCharCodes[index++] = pCharCodes[i]; + if (pKernings[i] != 0 && i != nChars - 1) { + m_pCharCodes[index] = (FX_DWORD) - 1; + m_pCharPos[index - 1] = pKernings[i]; + index ++; + } + } + } else { + int offset = 0; + m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pCharCodes[0]; + } + RecalcPositionData(); +} +FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const +{ + FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + if (!bVertWriting) { + return pFont->GetCharWidthF(charcode, 0) * fontsize; + } else { + FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); + return pCIDFont->GetVertWidth(CID) * fontsize; + } +} +FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const +{ + CPDF_Font* pFont = m_TextState.GetFont(); + FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32); + if (charCode != (FX_DWORD) - 1) { + return GetCharWidth(charCode); + } + FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f; + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + FX_RECT fontRect; + pFont->GetFontBBox(fontRect); + fontSize *= bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width(); + return fontSize; +} +void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const +{ + FX_FLOAT curpos = 0; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; + int count = 0; + for (int i = 0; i < m_nChars; i ++) { + FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i]; + if (charcode == (FX_DWORD) - 1) { + continue; + } + if( count != index) { + count++; + continue; + } + FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0; + FX_RECT char_rect; + pFont->GetCharBBox(charcode, char_rect, 0); + if (!bVertWriting) { + rect.left = curpos + char_rect.left * fontsize; + rect.right = curpos + char_rect.right * fontsize; + rect.top = char_rect.top * fontsize; + rect.bottom = char_rect.bottom * fontsize; + } else { + FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); + short vx, vy; + pCIDFont->GetVertOrigin(CID, vx, vy); + char_rect.left -= vx; + char_rect.right -= vx; + char_rect.top -= vy; + char_rect.bottom -= vy; + rect.left = char_rect.left * fontsize; + rect.right = char_rect.right * fontsize; + rect.top = curpos + char_rect.top * fontsize; + rect.bottom = curpos + char_rect.bottom * fontsize; + } + return; + } +} +void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, FX_FLOAT horz_scale, int level) +{ + FX_FLOAT curpos = 0; + FX_FLOAT min_x = 10000 * 1.0f, max_x = -10000 * 1.0f, min_y = 10000 * 1.0f, max_y = -10000 * 1.0f; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + FX_FLOAT fontsize = m_TextState.GetFontSize(); + for (int i = 0; i < m_nChars; i ++) { + FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i]; + if (charcode == (FX_DWORD) - 1) { + curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000; + continue; + } + if (i) { + m_pCharPos[i - 1] = curpos; + } + FX_RECT char_rect; + pFont->GetCharBBox(charcode, char_rect, level); + FX_FLOAT charwidth; + if (!bVertWriting) { + if (min_y > char_rect.top) { + min_y = (FX_FLOAT)char_rect.top; + } + if (max_y < char_rect.top) { + max_y = (FX_FLOAT)char_rect.top; + } + if (min_y > char_rect.bottom) { + min_y = (FX_FLOAT)char_rect.bottom; + } + if (max_y < char_rect.bottom) { + max_y = (FX_FLOAT)char_rect.bottom; + } + FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; + FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; + if (min_x > char_left) { + min_x = char_left; + } + if (max_x < char_left) { + max_x = char_left; + } + if (min_x > char_right) { + min_x = char_right; + } + if (max_x < char_right) { + max_x = char_right; + } + charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000; + } else { + FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); + short vx, vy; + pCIDFont->GetVertOrigin(CID, vx, vy); + char_rect.left -= vx; + char_rect.right -= vx; + char_rect.top -= vy; + char_rect.bottom -= vy; + if (min_x > char_rect.left) { + min_x = (FX_FLOAT)char_rect.left; + } + if (max_x < char_rect.left) { + max_x = (FX_FLOAT)char_rect.left; + } + if (min_x > char_rect.right) { + min_x = (FX_FLOAT)char_rect.right; + } + if (max_x < char_rect.right) { + max_x = (FX_FLOAT)char_rect.right; + } + FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; + FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; + if (min_y > char_top) { + min_y = char_top; + } + if (max_y < char_top) { + max_y = char_top; + } + if (min_y > char_bottom) { + min_y = char_bottom; + } + if (max_y < char_bottom) { + max_y = char_bottom; + } + charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; + } + curpos += charwidth; + if (charcode == ' ' && (pCIDFont == NULL || pCIDFont->GetCharSize(32) == 1)) { + curpos += m_TextState.GetObject()->m_WordSpace; + } + curpos += m_TextState.GetObject()->m_CharSpace; + } + if (bVertWriting) { + if (pTextAdvanceX) { + *pTextAdvanceX = 0; + } + if (pTextAdvanceY) { + *pTextAdvanceY = curpos; + } + min_x = min_x * fontsize / 1000; + max_x = max_x * fontsize / 1000; + } else { + if (pTextAdvanceX) { + *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale); + } + if (pTextAdvanceY) { + *pTextAdvanceY = 0; + } + min_y = min_y * fontsize / 1000; + max_y = max_y * fontsize / 1000; + } + CFX_AffineMatrix matrix; + GetTextMatrix(&matrix); + m_Left = min_x; + m_Right = max_x; + m_Bottom = min_y; + m_Top = max_y; + matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); + int textmode = m_TextState.GetObject()->m_TextMode; + if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) { + FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; + m_Left -= half_width; + m_Right += half_width; + m_Top += half_width; + m_Bottom -= half_width; + } +} +void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const +{ + FX_FLOAT curpos = 0; + int count = 0; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + FX_FLOAT fontsize = m_TextState.GetFontSize(); + int index = 0; + for (int i = 0; i < m_nChars; i ++) { + FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i]; + if (charcode == (FX_DWORD) - 1) { + continue; + } + pPosArray[index++] = i ? m_pCharPos[i - 1] : 0; + FX_FLOAT charwidth; + if (bVertWriting) { + FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); + charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; + } else { + charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; + } + pPosArray[index] = pPosArray[index - 1] + charwidth; + index++; + } +} +void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix) +{ + m_TextState.GetModify(); + CFX_AffineMatrix text_matrix; + GetTextMatrix(&text_matrix); + text_matrix.Concat(matrix); + FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); + pTextMatrix[0] = text_matrix.GetA(); + pTextMatrix[1] = text_matrix.GetC(); + pTextMatrix[2] = text_matrix.GetB(); + pTextMatrix[3] = text_matrix.GetD(); + m_PosX = text_matrix.GetE(); + m_PosY = text_matrix.GetF(); + CalcPositionData(NULL, NULL, 0); +} +void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) +{ + FX_FLOAT dx = x - m_PosX; + FX_FLOAT dy = y - m_PosY; + m_PosX = x; + m_PosY = y; + m_Left += dx; + m_Right += dx; + m_Top += dy; + m_Bottom += dy; +} +void CPDF_TextObject::SetData(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, FX_FLOAT x, FX_FLOAT y) +{ + ASSERT(m_nChars == 0); + m_nChars = nChars; + m_PosX = x; + m_PosY = y; + if (nChars == 0) { + return; + } + if (nChars == 1) { + m_pCharCodes = (FX_DWORD*)(FX_UINTPTR) * pCharCodes; + } else { + m_pCharCodes = FX_Alloc(FX_DWORD, nChars); + FXSYS_memcpy32(m_pCharCodes, pCharCodes, sizeof(FX_DWORD)*nChars); + m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); + FXSYS_memcpy32(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1)); + } + RecalcPositionData(); +} +void CPDF_TextObject::SetTextState(CPDF_TextState TextState) +{ + m_TextState = TextState; + CalcPositionData(NULL, NULL, 0); +} +CPDF_ShadingObject::CPDF_ShadingObject() +{ + m_pShading = NULL; + m_Type = PDFPAGE_SHADING; +} +CPDF_ShadingObject::~CPDF_ShadingObject() +{ + CPDF_ShadingPattern* pShading = m_pShading; + if (pShading && pShading->m_pDocument) { + pShading->m_pDocument->GetPageData()->ReleasePattern(pShading->m_pShadingObj); + } +} +void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc) +{ + CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc; + m_pShading = pSrcObj->m_pShading; + if (m_pShading && m_pShading->m_pDocument) { + CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData(); + m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(m_pShading->m_pShadingObj, m_pShading->m_bShadingObj, &m_pShading->m_ParentMatrix); + } + m_Matrix = pSrcObj->m_Matrix; +} +void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix) +{ + if (!m_ClipPath.IsNull()) { + m_ClipPath.GetModify(); + m_ClipPath.Transform(matrix); + } + m_Matrix.Concat(matrix); + if (!m_ClipPath.IsNull()) { + CalcBoundingBox(); + } else { + matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); + } +} +void CPDF_ShadingObject::CalcBoundingBox() +{ + if (m_ClipPath.IsNull()) { + return; + } + CFX_FloatRect rect = m_ClipPath.GetClipBox(); + m_Left = rect.left; + m_Bottom = rect.bottom; + m_Right = rect.right; + m_Top = rect.top; +} +CPDF_FormObject::~CPDF_FormObject() +{ + if (m_pForm) { + delete m_pForm; + } +} +void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix) +{ + m_FormMatrix.Concat(matrix); + CalcBoundingBox(); +} +void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc) +{ + const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc; + if (m_pForm) { + delete m_pForm; + } + m_pForm = pSrcObj->m_pForm->Clone(); + m_FormMatrix = pSrcObj->m_FormMatrix; +} +void CPDF_FormObject::CalcBoundingBox() +{ + CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); + form_rect.Transform(&m_FormMatrix); + m_Left = form_rect.left; + m_Bottom = form_rect.bottom; + m_Right = form_rect.right; + m_Top = form_rect.top; +} +CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) : m_ObjectList(128) +{ + m_bBackgroundAlphaNeeded = FALSE; + m_bReleaseMembers = bReleaseMembers; + m_ParseState = PDF_CONTENT_NOT_PARSED; + m_pParser = NULL; + m_pFormStream = NULL; + m_pResources = NULL; +} +CPDF_PageObjects::~CPDF_PageObjects() +{ + if (m_pParser) { + delete m_pParser; + } + if (!m_bReleaseMembers) { + return; + } + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + if (!pPageObj) { + continue; + } + pPageObj->Release(); + } +} +void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause) +{ + if (m_pParser == NULL) { + return; + } + m_pParser->Continue(pPause); + if (m_pParser->GetStatus() == CPDF_ContentParser::Done) { + m_ParseState = PDF_CONTENT_PARSED; + delete m_pParser; + m_pParser = NULL; + } +} +int CPDF_PageObjects::EstimateParseProgress() const +{ + if (m_pParser == NULL) { + return m_ParseState == PDF_CONTENT_PARSED ? 100 : 0; + } + return m_pParser->EstimateProgress(); +} +FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, CPDF_PageObject* pNewObject) +{ + if (posInsertAfter == NULL) { + return m_ObjectList.AddHead(pNewObject); + } else { + return m_ObjectList.InsertAfter(posInsertAfter, pNewObject); + } +} +int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const +{ + int index = 0; + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + if (pThisObj == pObj) { + return index; + } + index ++; + } + return -1; +} +CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const +{ + FX_POSITION pos = m_ObjectList.FindIndex(index); + if (pos == NULL) { + return NULL; + } + return (CPDF_PageObject*)m_ObjectList.GetAt(pos); +} +void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix) +{ + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + pObj->Transform(matrix); + } +} +CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const +{ + if (m_ObjectList.GetCount() == 0) { + return CFX_FloatRect(0, 0, 0, 0); + } + FX_FLOAT left, right, top, bottom; + left = bottom = 1000000 * 1.0f; + right = top = -1000000 * 1.0f; + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + if (left > pObj->m_Left) { + left = pObj->m_Left; + } + if (right < pObj->m_Right) { + right = pObj->m_Right; + } + if (top < pObj->m_Top) { + top = pObj->m_Top; + } + if (bottom > pObj->m_Bottom) { + bottom = pObj->m_Bottom; + } + } + return CFX_FloatRect(left, bottom, right, top); +} +void CPDF_PageObjects::LoadTransInfo() +{ + if (m_pFormDict == NULL) { + return; + } + CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group")); + if (pGroup == NULL) { + return; + } + if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) { + return; + } + m_Transparency |= PDFTRANS_GROUP; + if (pGroup->GetInteger(FX_BSTRC("I"))) { + m_Transparency |= PDFTRANS_ISOLATED; + } + if (pGroup->GetInteger(FX_BSTRC("K"))) { + m_Transparency |= PDFTRANS_KNOCKOUT; + } +} +void CPDF_PageObjects::ClearCacheObjects() +{ + m_ParseState = PDF_CONTENT_NOT_PARSED; + if (m_pParser) { + delete m_pParser; + } + m_pParser = NULL; + if (m_bReleaseMembers) { + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + if (!pPageObj) { + continue; + } + pPageObj->Release(); + } + } + m_ObjectList.RemoveAll(); +} +CPDF_Page::CPDF_Page() +{ + m_pPageRender = NULL; +} +void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BOOL bPageCache) +{ + m_pDocument = (CPDF_Document*)pDocument; + m_pFormDict = pPageDict; + if (bPageCache) { + m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this); + } + if (pPageDict == NULL) { + m_PageWidth = m_PageHeight = 100 * 1.0f; + m_pPageResources = m_pResources = NULL; + return; + } + m_pResources = GetPageAttr(FX_BSTRC("Resources"))->GetDict(); + m_pPageResources = m_pResources; + CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate")); + int rotate = 0; + if (pRotate) { + rotate = pRotate->GetInteger() / 90 % 4; + } + if (rotate < 0) { + rotate += 4; + } + CPDF_Array* pMediaBox, *pCropBox; + pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox")); + CFX_FloatRect mediabox; + if (pMediaBox) { + mediabox = pMediaBox->GetRect(); + mediabox.Normalize(); + } + if (mediabox.IsEmpty()) { + mediabox = CFX_FloatRect(0, 0, 612, 792); + } + pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox")); + if (pCropBox) { + m_BBox = pCropBox->GetRect(); + m_BBox.Normalize(); + } + if (m_BBox.IsEmpty()) { + m_BBox = mediabox; + } else { + m_BBox.Intersect(mediabox); + } + if (rotate % 2) { + m_PageHeight = m_BBox.right - m_BBox.left; + m_PageWidth = m_BBox.top - m_BBox.bottom; + } else { + m_PageWidth = m_BBox.right - m_BBox.left; + m_PageHeight = m_BBox.top - m_BBox.bottom; + } + switch (rotate) { + case 0: + m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); + break; + case 1: + m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); + break; + case 2: + m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); + break; + case 3: + m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); + break; + } + m_Transparency = PDFTRANS_ISOLATED; + LoadTransInfo(); +} +void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) +{ + if (bReParse) { + ClearCacheObjects(); + } + if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) { + return; + } + m_pParser = FX_NEW CPDF_ContentParser; + m_pParser->Start(this, pOptions); + m_ParseState = PDF_CONTENT_PARSING; +} +void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) +{ + StartParse(pOptions, bReParse); + ContinueParse(NULL); +} +CPDF_Page::~CPDF_Page() +{ + if (m_pPageRender) { + CPDF_RenderModuleDef* pModule = CPDF_ModuleMgr::Get()->GetRenderModule(); + pModule->DestroyPageCache(m_pPageRender); + } +} +CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, FX_BSTR name) +{ + int level = 0; + while (1) { + CPDF_Object* pObj = pPageDict->GetElementValue(name); + if (pObj) { + return pObj; + } + CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent")); + if (!pParent || pParent == pPageDict) { + return NULL; + } + pPageDict = pParent; + level ++; + if (level == 1000) { + return NULL; + } + } +} +CPDF_Object* CPDF_Page::GetPageAttr(FX_BSTR name) const +{ + return FPDFAPI_GetPageAttr(m_pFormDict, name); +} +CPDF_Form::CPDF_Form(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Stream* pFormStream, CPDF_Dictionary* pParentResources) +{ + m_pDocument = pDoc; + m_pFormStream = pFormStream; + m_pFormDict = pFormStream->GetDict(); + m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources")); + m_pPageResources = pPageResources; + if (m_pResources == NULL) { + m_pResources = pParentResources; + } + if (m_pResources == NULL) { + m_pResources = pPageResources; + } + m_Transparency = 0; + LoadTransInfo(); +} +CPDF_Form::~CPDF_Form() +{ +} +void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix, + CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) +{ + if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) { + return; + } + m_pParser = FX_NEW CPDF_ContentParser; + m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions, level); + m_ParseState = PDF_CONTENT_PARSING; +} +void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix, + CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) +{ + StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level); + ContinueParse(NULL); +} +CPDF_Form* CPDF_Form::Clone() const +{ + CPDF_Form* pClone = FX_NEW CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources); + FX_POSITION pos = m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos); + pClone->m_ObjectList.AddTail(pObj->Clone()); + } + return pClone; +} +void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos, + int xSize, int ySize, int iRotate) const +{ + if (m_PageWidth == 0 || m_PageHeight == 0) { + return; + } + CFX_AffineMatrix display_matrix; + int x0, y0, x1, y1, x2, y2; + iRotate %= 4; + switch (iRotate) { + case 0: + x0 = xPos; + y0 = yPos + ySize; + x1 = xPos; + y1 = yPos; + x2 = xPos + xSize; + y2 = yPos + ySize; + break; + case 1: + x0 = xPos; + y0 = yPos; + x1 = xPos + xSize; + y1 = yPos; + x2 = xPos; + y2 = yPos + ySize; + break; + case 2: + x0 = xPos + xSize; + y0 = yPos; + x1 = xPos + xSize; + y1 = yPos + ySize; + x2 = xPos; + y2 = yPos; + break; + case 3: + x0 = xPos + xSize; + y0 = yPos + ySize; + x1 = xPos; + y1 = yPos + ySize; + x2 = xPos + xSize; + y2 = yPos; + break; + } + display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth), + FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth), + FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight), + FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight), + (FX_FLOAT)x0, (FX_FLOAT)y0); + matrix = m_PageMatrix; + matrix.Concat(display_matrix); +} +CPDF_ParseOptions::CPDF_ParseOptions() +{ + m_bTextOnly = FALSE; + m_bMarkedContent = TRUE; + m_bSeparateForm = TRUE; + m_bDecodeInlineImage = FALSE; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp index 44b4fc0b1d..8c274b2607 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp @@ -1,1401 +1,1401 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "pageint.h"
-#include <limits.h>
-void sRGB_to_AdobeCMYK(FX_FLOAT R, FX_FLOAT G, FX_FLOAT B, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k)
-{
- c = 1.0f - R;
- m = 1.0f - G;
- y = 1.0f - B;
- k = c;
- if (m < k) {
- k = m;
- }
- if (y < k) {
- k = y;
- }
-}
-CPDF_DeviceCS::CPDF_DeviceCS(int family)
-{
- m_Family = family;
- if (m_Family == PDFCS_DEVICERGB) {
- m_nComponents = 3;
- } else if (m_Family == PDFCS_DEVICEGRAY) {
- m_nComponents = 1;
- } else {
- m_nComponents = 4;
- }
-}
-FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- if (m_Family == PDFCS_DEVICERGB) {
- R = pBuf[0];
- if (R < 0) {
- R = 0;
- } else if (R > 1) {
- R = 1;
- }
- G = pBuf[1];
- if (G < 0) {
- G = 0;
- } else if (G > 1) {
- G = 1;
- }
- B = pBuf[2];
- if (B < 0) {
- B = 0;
- } else if (B > 1) {
- B = 1;
- }
- } else if (m_Family == PDFCS_DEVICEGRAY) {
- R = *pBuf;
- if (R < 0) {
- R = 0;
- } else if (R > 1) {
- R = 1;
- }
- G = B = R;
- } else if (m_Family == PDFCS_DEVICECMYK) {
- if (!m_dwStdConversion) {
- AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B);
- } else {
- FX_FLOAT k = pBuf[3];
- R = 1.0f - FX_MIN(1.0f, pBuf[0] + k);
- G = 1.0f - FX_MIN(1.0f, pBuf[1] + k);
- B = 1.0f - FX_MIN(1.0f, pBuf[2] + k);
- }
- } else {
- ASSERT(m_Family == PDFCS_PATTERN);
- R = G = B = 0;
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
-{
- if (m_Family != PDFCS_DEVICECMYK) {
- return FALSE;
- }
- c = pBuf[0];
- m = pBuf[1];
- y = pBuf[2];
- k = pBuf[3];
- return TRUE;
-}
-FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
-{
- if (m_Family == PDFCS_DEVICERGB) {
- pBuf[0] = R;
- pBuf[1] = G;
- pBuf[2] = B;
- return TRUE;
- } else if (m_Family == PDFCS_DEVICEGRAY) {
- if (R == G && R == B) {
- *pBuf = R;
- return TRUE;
- } else {
- return FALSE;
- }
- } else if (m_Family == PDFCS_DEVICECMYK) {
- sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const
-{
- if (m_Family == PDFCS_DEVICERGB) {
- AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
- return TRUE;
- } else if (m_Family == PDFCS_DEVICEGRAY) {
- return FALSE;
- } else if (m_Family == PDFCS_DEVICECMYK) {
- pBuf[0] = c;
- pBuf[1] = m;
- pBuf[2] = y;
- pBuf[3] = k;
- return TRUE;
- }
- return FALSE;
-}
-static void ReverseRGB(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels)
-{
- if (pDestBuf == pSrcBuf)
- for (int i = 0; i < pixels; i ++) {
- FX_BYTE temp = pDestBuf[2];
- pDestBuf[2] = pDestBuf[0];
- pDestBuf[0] = temp;
- pDestBuf += 3;
- }
- else
- for (int i = 0; i < pixels; i ++) {
- *pDestBuf ++ = pSrcBuf[2];
- *pDestBuf ++ = pSrcBuf[1];
- *pDestBuf ++ = pSrcBuf[0];
- pSrcBuf += 3;
- }
-}
-void CPDF_DeviceCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- if (bTransMask && m_Family == PDFCS_DEVICECMYK) {
- for (int i = 0; i < pixels; i ++) {
- int k = 255 - pSrcBuf[3];
- pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255;
- pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255;
- pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255;
- pDestBuf += 3;
- pSrcBuf += 4;
- }
- return;
- }
- if (m_Family == PDFCS_DEVICERGB) {
- ReverseRGB(pDestBuf, pSrcBuf, pixels);
- } else if (m_Family == PDFCS_DEVICEGRAY) {
- for (int i = 0; i < pixels; i ++) {
- *pDestBuf ++ = pSrcBuf[i];
- *pDestBuf ++ = pSrcBuf[i];
- *pDestBuf ++ = pSrcBuf[i];
- }
- } else {
- for (int i = 0; i < pixels; i ++) {
- if (!m_dwStdConversion) {
- AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3], pDestBuf[2], pDestBuf[1], pDestBuf[0]);
- } else {
- FX_BYTE k = pSrcBuf[3];
- pDestBuf[2] = 255 - FX_MIN(255, pSrcBuf[0] + k);
- pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k);
- pDestBuf[0] = 255 - FX_MIN(255, pSrcBuf[2] + k);
- }
- pSrcBuf += 4;
- pDestBuf += 3;
- }
- }
-}
-const FX_BYTE g_sRGBSamples1[] = {
- 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, 32,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61,
- 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, 68, 69, 70, 70,
- 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76, 77, 77, 78, 78, 79,
- 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 85, 86,
- 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 91, 91, 91, 92, 92, 93,
- 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 97, 97, 98, 98, 98, 99,
- 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104,
- 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110,
- 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115,
- 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
-};
-const FX_BYTE g_sRGBSamples2[] = {
- 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
- 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
- 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
- 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
- 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
- 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
- 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
- 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
- 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
- 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
- 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
- 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
- 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
-};
-static void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B)
-{
- FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
- FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
- FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
- if (R1 > 1) {
- R1 = 1;
- }
- if (R1 < 0) {
- R1 = 0;
- }
- if (G1 > 1) {
- G1 = 1;
- }
- if (G1 < 0) {
- G1 = 0;
- }
- if (B1 > 1) {
- B1 = 1;
- }
- if (B1 < 0) {
- B1 = 0;
- }
- int scale = (int)(R1 * 1023);
- if (scale < 0) {
- scale = 0;
- }
- if (scale < 192) {
- R = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- R = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
- scale = (int)(G1 * 1023);
- if (scale < 0) {
- scale = 0;
- }
- if (scale < 192) {
- G = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- G = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
- scale = (int)(B1 * 1023);
- if (scale < 0) {
- scale = 0;
- }
- if (scale < 192) {
- B = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- B = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
-}
-class CPDF_CalGray : public CPDF_ColorSpace
-{
-public:
- CPDF_CalGray();
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
- FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Gamma;
-};
-CPDF_CalGray::CPDF_CalGray()
-{
- m_Family = PDFCS_CALGRAY;
- m_nComponents = 1;
-}
-FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Dictionary* pDict = pArray->GetDict(1);
- CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
- int i;
- for (i = 0; i < 3; i ++) {
- m_WhitePoint[i] = pParam->GetNumber(i);
- }
- pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
- for (i = 0; i < 3; i ++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
- }
- m_Gamma = pDict->GetNumber(FX_BSTRC("Gamma"));
- if (m_Gamma == 0) {
- m_Gamma = 1.0f;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- R = G = B = *pBuf;
- return TRUE;
-}
-FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
-{
- if (R == G && R == B) {
- *pBuf = R;
- return TRUE;
- } else {
- return FALSE;
- }
-}
-void CPDF_CalGray::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- for (int i = 0; i < pixels; i ++) {
- *pDestBuf ++ = pSrcBuf[i];
- *pDestBuf ++ = pSrcBuf[i];
- *pDestBuf ++ = pSrcBuf[i];
- }
-}
-class CPDF_CalRGB : public CPDF_ColorSpace
-{
-public:
- CPDF_CalRGB();
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
- FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Gamma[3];
- FX_FLOAT m_Matrix[9];
- FX_BOOL m_bGamma, m_bMatrix;
-};
-CPDF_CalRGB::CPDF_CalRGB()
-{
- m_Family = PDFCS_CALRGB;
- m_nComponents = 3;
-}
-FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Dictionary* pDict = pArray->GetDict(1);
- CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
- int i;
- for (i = 0; i < 3; i ++) {
- m_WhitePoint[i] = pParam->GetNumber(i);
- }
- pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
- for (i = 0; i < 3; i ++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
- }
- pParam = pDict->GetArray(FX_BSTRC("Gamma"));
- if (pParam) {
- m_bGamma = TRUE;
- for (i = 0; i < 3; i ++) {
- m_Gamma[i] = pParam->GetNumber(i);
- }
- } else {
- m_bGamma = FALSE;
- }
- pParam = pDict->GetArray(FX_BSTRC("Matrix"));
- if (pParam) {
- m_bMatrix = TRUE;
- for (i = 0; i < 9; i ++) {
- m_Matrix[i] = pParam->GetNumber(i);
- }
- } else {
- m_bMatrix = FALSE;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- FX_FLOAT A_ = pBuf[0];
- FX_FLOAT B_ = pBuf[1];
- FX_FLOAT C_ = pBuf[2];
- if (m_bGamma) {
- A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
- B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
- C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
- }
- FX_FLOAT X, Y, Z;
- if (m_bMatrix) {
- X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
- Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
- Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
- } else {
- X = A_;
- Y = B_;
- Z = C_;
- }
- XYZ_to_sRGB(X, Y, Z, R, G, B);
- return TRUE;
-}
-FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
-{
- pBuf[0] = R;
- pBuf[1] = G;
- pBuf[2] = B;
- return TRUE;
-}
-void CPDF_CalRGB::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- if (bTransMask) {
- FX_FLOAT Cal[3];
- FX_FLOAT R, G, B;
- for(int i = 0; i < pixels; i ++) {
- Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
- Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
- Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
- GetRGB(Cal, R, G, B);
- pDestBuf[0] = FXSYS_round(B * 255);
- pDestBuf[1] = FXSYS_round(G * 255);
- pDestBuf[2] = FXSYS_round(R * 255);
- pSrcBuf += 3;
- pDestBuf += 3;
- }
- }
- ReverseRGB(pDestBuf, pSrcBuf, pixels);
-}
-class CPDF_LabCS : public CPDF_ColorSpace
-{
-public:
- CPDF_LabCS()
- {
- m_Family = PDFCS_LAB;
- m_nComponents = 3;
- }
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const;
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
- virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Ranges[4];
-};
-FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Dictionary* pDict = pArray->GetDict(1);
- CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
- int i;
- for (i = 0; i < 3; i ++) {
- m_WhitePoint[i] = pParam->GetNumber(i);
- }
- pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
- for (i = 0; i < 3; i ++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
- }
- pParam = pDict->GetArray(FX_BSTRC("Range"));
- const FX_FLOAT def_ranges[4] = { -100 * 1.0f, 100 * 1.0f, -100 * 1.0f, 100 * 1.0f};
- for (i = 0; i < 4; i ++) {
- m_Ranges[i] = pParam ? pParam->GetNumber(i) : def_ranges[i];
- }
- return TRUE;
-}
-void CPDF_LabCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
-{
- value = 0;
- if (iComponent == 0) {
- min = 0;
- max = 100 * 1.0f;
- } else {
- min = m_Ranges[iComponent * 2 - 2];
- max = m_Ranges[iComponent * 2 - 1];
- if (value < min) {
- value = min;
- } else if (value > max) {
- value = max;
- }
- }
-}
-FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- FX_FLOAT Lstar = pBuf[0];
- FX_FLOAT astar = pBuf[1];
- FX_FLOAT bstar = pBuf[2];
- FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
- FX_FLOAT L = M + astar / 500.0f;
- FX_FLOAT N = M - bstar / 200.0f;
- FX_FLOAT X, Y, Z;
- if (L < 0.2069f) {
- X = 0.957f * 0.12842f * (L - 0.1379f);
- } else {
- X = 0.957f * L * L * L;
- }
- if (M < 0.2069f) {
- Y = 0.12842f * (M - 0.1379f);
- } else {
- Y = M * M * M;
- }
- if (N < 0.2069f) {
- Z = 1.0889f * 0.12842f * (N - 0.1379f);
- } else {
- Z = 1.0889f * N * N * N;
- }
- XYZ_to_sRGB(X, Y, Z, R, G, B);
- return TRUE;
-}
-FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
-{
- return FALSE;
-}
-void CPDF_LabCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- for (int i = 0; i < pixels; i ++) {
- FX_FLOAT lab[3];
- FX_FLOAT R, G, B;
- lab[0] = (pSrcBuf[0] * 100 / 255.0f);
- lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
- lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
- GetRGB(lab, R, G, B);
- pDestBuf[0] = (FX_INT32)(B * 255);
- pDestBuf[1] = (FX_INT32)(G * 255);
- pDestBuf[2] = (FX_INT32)(R * 255);
- pDestBuf += 3;
- pSrcBuf += 3;
- }
-}
-CPDF_IccProfile::CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents)
-{
- m_bsRGB = nComponents == 3 && dwSize == 3144 && FXSYS_memcmp32(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0;
- m_pTransform = NULL;
- if (!m_bsRGB && CPDF_ModuleMgr::Get()->GetIccModule()) {
- m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(pData, dwSize, nComponents);
- }
-}
-CPDF_IccProfile::~CPDF_IccProfile()
-{
- if (m_pTransform) {
- CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
- }
-}
-class CPDF_ICCBasedCS : public CPDF_ColorSpace
-{
-public:
- CPDF_ICCBasedCS();
- virtual ~CPDF_ICCBasedCS();
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- void GetDefaultValue(int i, FX_FLOAT& min, FX_FLOAT& max) const
- {
- min = m_pRanges[i * 2];
- max = m_pRanges[i * 2 + 1];
- }
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const;
- FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
- virtual void EnableStdConversion(FX_BOOL bEnabled);
- virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
- FX_FLOAT* m_pRanges;
- CPDF_IccProfile* m_pProfile;
- CPDF_ColorSpace* m_pAlterCS;
- FX_LPBYTE m_pCache;
- FX_BOOL m_bOwn;
-};
-CPDF_ICCBasedCS::CPDF_ICCBasedCS()
-{
- m_pAlterCS = NULL;
- m_pProfile = NULL;
- m_Family = PDFCS_ICCBASED;
- m_pCache = NULL;
- m_pRanges = NULL;
- m_bOwn = FALSE;
-}
-CPDF_ICCBasedCS::~CPDF_ICCBasedCS()
-{
- if (m_pCache) {
- FX_Free(m_pCache);
- }
- if (m_pRanges) {
- FX_Free(m_pRanges);
- }
- if (m_pAlterCS && m_bOwn) {
- m_pAlterCS->ReleaseCS();
- }
- if (m_pProfile && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseIccProfile(NULL, m_pProfile);
- }
-}
-FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Stream* pStream = pArray->GetStream(1);
- if (pStream == NULL) {
- return FALSE;
- }
- m_nComponents = pStream->GetDict()->GetInteger(FX_BSTRC("N"));
- if (m_nComponents < 0 || m_nComponents > (1 << 16)) {
- return FALSE;
- }
- CPDF_Array* pRanges = pStream->GetDict()->GetArray(FX_BSTRC("Range"));
- m_pRanges = FX_Alloc(FX_FLOAT, m_nComponents * 2);
- for (int i = 0; i < m_nComponents * 2; i ++) {
- if (pRanges) {
- m_pRanges[i] = pRanges->GetNumber(i);
- } else if (i % 2) {
- m_pRanges[i] = 1.0f;
- } else {
- m_pRanges[i] = 0;
- }
- }
- m_pProfile = pDoc->LoadIccProfile(pStream, m_nComponents);
- if (!m_pProfile) {
- return FALSE;
- }
- if (m_pProfile->m_pTransform == NULL) {
- CPDF_Object* pAlterCSObj = pStream->GetDict()->GetElementValue(FX_BSTRC("Alternate"));
- if (pAlterCSObj) {
- CPDF_ColorSpace* alter_cs = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
- if (alter_cs) {
- if (alter_cs->CountComponents() > m_nComponents) {
- alter_cs->ReleaseCS();
- } else {
- m_pAlterCS = alter_cs;
- m_bOwn = TRUE;
- }
- }
- }
- if (!m_pAlterCS) {
- if (m_nComponents == 3) {
- m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
- } else if (m_nComponents == 4) {
- m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
- } else {
- m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
- }
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- if (m_pProfile && m_pProfile->m_bsRGB) {
- R = pBuf[0];
- G = pBuf[1];
- B = pBuf[2];
- return TRUE;
- }
- ICodec_IccModule *pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
- if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
- if (m_pAlterCS) {
- m_pAlterCS->GetRGB(pBuf, R, G, B);
- } else {
- R = G = B = 0.0f;
- }
- return TRUE;
- }
- FX_FLOAT rgb[3];
- pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
- R = rgb[0];
- G = rgb[1];
- B = rgb[2];
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
-{
- if (m_nComponents != 4) {
- return FALSE;
- }
- c = pBuf[0];
- m = pBuf[1];
- y = pBuf[2];
- k = pBuf[3];
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
-{
- return FALSE;
-}
-void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled)
-{
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAlterCS) {
- m_pAlterCS->EnableStdConversion(bEnabled);
- }
-}
-void CPDF_ICCBasedCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- if (m_pProfile->m_bsRGB) {
- ReverseRGB(pDestBuf, pSrcBuf, pixels);
- } else if (m_pProfile->m_pTransform) {
- int nMaxColors = 1;
- for (int i = 0; i < m_nComponents; i ++) {
- nMaxColors *= 52;
- }
- if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
- CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
- } else {
- if (m_pCache == NULL) {
- ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc(FX_BYTE, nMaxColors * 3);
- FX_LPBYTE temp_src = FX_Alloc(FX_BYTE, nMaxColors * m_nComponents);
- FX_LPBYTE pSrc = temp_src;
- for (int i = 0; i < nMaxColors; i ++) {
- FX_DWORD color = i;
- FX_DWORD order = nMaxColors / 52;
- for (int c = 0; c < m_nComponents; c ++) {
- *pSrc++ = (FX_BYTE)(color / order * 5);
- color %= order;
- order /= 52;
- }
- }
- CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
- FX_Free(temp_src);
- }
- for (int i = 0; i < pixels; i ++) {
- int index = 0;
- for (int c = 0; c < m_nComponents; c ++) {
- index = index * 52 + (*pSrcBuf) / 5;
- pSrcBuf ++;
- }
- index *= 3;
- *pDestBuf++ = m_pCache[index];
- *pDestBuf++ = m_pCache[index + 1];
- *pDestBuf++ = m_pCache[index + 2];
- }
- }
- } else if (m_pAlterCS) {
- m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, image_height);
- }
-}
-class CPDF_IndexedCS : public CPDF_ColorSpace
-{
-public:
- CPDF_IndexedCS();
- virtual ~CPDF_IndexedCS();
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- void GetDefaultValue(int iComponent, FX_FLOAT& min, FX_FLOAT& max) const
- {
- min = 0;
- max = (FX_FLOAT)m_MaxIndex;
- }
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual CPDF_ColorSpace* GetBaseCS() const
- {
- return m_pBaseCS;
- }
- virtual void EnableStdConversion(FX_BOOL bEnabled);
- CPDF_ColorSpace* m_pBaseCS;
- int m_nBaseComponents;
- int m_MaxIndex;
- CFX_ByteString m_Table;
- FX_FLOAT* m_pCompMinMax;
-};
-CPDF_IndexedCS::CPDF_IndexedCS()
-{
- m_pBaseCS = NULL;
- m_Family = PDFCS_INDEXED;
- m_nComponents = 1;
- m_pCompMinMax = NULL;
-}
-CPDF_IndexedCS::~CPDF_IndexedCS()
-{
- if (m_pCompMinMax) {
- FX_Free(m_pCompMinMax);
- }
- CPDF_ColorSpace* pCS = m_pBaseCS;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
-}
-FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- if (pArray->GetCount() < 4) {
- return FALSE;
- }
- CPDF_Object* pBaseObj = pArray->GetElementValue(1);
- if (pBaseObj == m_pArray) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
- m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
- if (m_pBaseCS == NULL) {
- return FALSE;
- }
- m_nBaseComponents = m_pBaseCS->CountComponents();
- m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2);
- FX_FLOAT defvalue;
- for (int i = 0; i < m_nBaseComponents; i ++) {
- m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMinMax[i * 2 + 1]);
- m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
- }
- m_MaxIndex = pArray->GetInteger(2);
- CPDF_Object* pTableObj = pArray->GetElementValue(3);
- if (pTableObj == NULL) {
- return FALSE;
- }
- FX_LPCBYTE pTable = NULL;
- FX_DWORD size = 0;
- CPDF_StreamAcc* pStreamAcc = NULL;
- if (pTableObj->GetType() == PDFOBJ_STRING) {
- m_Table = ((CPDF_String*)pTableObj)->GetString();
- } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
- CPDF_StreamAcc acc;
- acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
- m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
- }
- return TRUE;
-}
-FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- int index = (FX_INT32)(*pBuf);
- if (index < 0 || index > m_MaxIndex) {
- return FALSE;
- }
- if (m_nBaseComponents) {
- if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
- (index + 1)*m_nBaseComponents > (int)m_Table.GetLength()) {
- R = G = B = 0;
- return FALSE;
- }
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
- FX_FLOAT* comps = Comps;
- FX_LPCBYTE pTable = m_Table;
- for (int i = 0; i < m_nBaseComponents; i ++) {
- comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
- }
- m_pBaseCS->GetRGB(comps, R, G, B);
- return TRUE;
-}
-void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled)
-{
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pBaseCS) {
- m_pBaseCS->EnableStdConversion(bEnabled);
- }
-}
-#define MAX_PATTERN_COLORCOMPS 16
-typedef struct _PatternValue {
- CPDF_Pattern* m_pPattern;
- int m_nComps;
- FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
-} PatternValue;
-CPDF_PatternCS::CPDF_PatternCS()
-{
- m_Family = PDFCS_PATTERN;
- m_pBaseCS = NULL;
- m_nComponents = 1;
-}
-CPDF_PatternCS::~CPDF_PatternCS()
-{
- CPDF_ColorSpace* pCS = m_pBaseCS;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
-}
-FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Object* pBaseCS = pArray->GetElementValue(1);
- if (pBaseCS == m_pArray) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
- m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
- if (m_pBaseCS) {
- m_nComponents = m_pBaseCS->CountComponents() + 1;
- if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
- return FALSE;
- }
- } else {
- m_nComponents = 1;
- }
- return TRUE;
-}
-FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- if (m_pBaseCS) {
- PatternValue* pvalue = (PatternValue*)pBuf;
- m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B);
- return TRUE;
- }
- R = G = B = 0.75f;
- return FALSE;
-}
-class CPDF_SeparationCS : public CPDF_ColorSpace
-{
-public:
- CPDF_SeparationCS();
- virtual ~CPDF_SeparationCS();
- virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
- {
- value = 1.0f;
- min = 0;
- max = 1.0f;
- }
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual void EnableStdConversion(FX_BOOL bEnabled);
- CPDF_ColorSpace* m_pAltCS;
- CPDF_Function* m_pFunc;
- enum {None, All, Colorant} m_Type;
-};
-CPDF_SeparationCS::CPDF_SeparationCS()
-{
- m_Family = PDFCS_SEPARATION;
- m_pAltCS = NULL;
- m_pFunc = NULL;
- m_nComponents = 1;
-}
-CPDF_SeparationCS::~CPDF_SeparationCS()
-{
- if (m_pAltCS) {
- m_pAltCS->ReleaseCS();
- }
- if (m_pFunc) {
- delete m_pFunc;
- }
-}
-FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CFX_ByteString name = pArray->GetString(1);
- if (name == FX_BSTRC("None")) {
- m_Type = None;
- } else {
- m_Type = Colorant;
- CPDF_Object* pAltCS = pArray->GetElementValue(2);
- if (pAltCS == m_pArray) {
- return FALSE;
- }
- m_pAltCS = Load(pDoc, pAltCS);
- CPDF_Object* pFuncObj = pArray->GetElementValue(3);
- if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
- m_pFunc = CPDF_Function::Load(pFuncObj);
- }
- if (m_pFunc && m_pAltCS && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
- delete m_pFunc;
- m_pFunc = NULL;
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- if (m_Type == None) {
- return FALSE;
- }
- if (m_pFunc == NULL) {
- if (m_pAltCS == NULL) {
- return FALSE;
- }
- int nComps = m_pAltCS->CountComponents();
- CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
- for (int i = 0; i < nComps; i ++) {
- results[i] = *pBuf;
- }
- m_pAltCS->GetRGB(results, R, G, B);
- return TRUE;
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
- int nresults;
- m_pFunc->Call(pBuf, 1, results, nresults);
- if (nresults == 0) {
- return FALSE;
- }
- if (m_pAltCS) {
- m_pAltCS->GetRGB(results, R, G, B);
- return TRUE;
- } else {
- R = G = B = 0;
- return FALSE;
- }
-}
-void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled)
-{
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS) {
- m_pAltCS->EnableStdConversion(bEnabled);
- }
-}
-class CPDF_DeviceNCS : public CPDF_ColorSpace
-{
-public:
- CPDF_DeviceNCS();
- virtual ~CPDF_DeviceNCS();
- virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const
- {
- value = 1.0f;
- min = 0;
- max = 1.0f;
- }
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual void EnableStdConversion(FX_BOOL bEnabled);
- CPDF_ColorSpace* m_pAltCS;
- CPDF_Function* m_pFunc;
-};
-CPDF_DeviceNCS::CPDF_DeviceNCS()
-{
- m_Family = PDFCS_DEVICEN;
- m_pAltCS = NULL;
- m_pFunc = NULL;
-}
-CPDF_DeviceNCS::~CPDF_DeviceNCS()
-{
- if (m_pFunc) {
- delete m_pFunc;
- }
- if (m_pAltCS) {
- m_pAltCS->ReleaseCS();
- }
-}
-FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
-{
- CPDF_Object* pObj = pArray->GetElementValue(1);
- if (!pObj) {
- return FALSE;
- }
- if (pObj->GetType() != PDFOBJ_ARRAY) {
- return FALSE;
- }
- m_nComponents = ((CPDF_Array*)pObj)->GetCount();
- CPDF_Object* pAltCS = pArray->GetElementValue(2);
- if (!pAltCS || pAltCS == m_pArray) {
- return FALSE;
- }
- m_pAltCS = Load(pDoc, pAltCS);
- m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
- if (m_pAltCS == NULL || m_pFunc == NULL) {
- return FALSE;
- }
- if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
-{
- if (m_pFunc == NULL) {
- return FALSE;
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
- int nresults;
- m_pFunc->Call(pBuf, m_nComponents, results, nresults);
- if (nresults == 0) {
- return FALSE;
- }
- m_pAltCS->GetRGB(results, R, G, B);
- return TRUE;
-}
-void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled)
-{
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS) {
- m_pAltCS->EnableStdConversion(bEnabled);
- }
-}
-CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family)
-{
- return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);;
-}
-CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name)
-{
- if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
- }
- if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
- }
- if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- }
- if (name == FX_BSTRC("Pattern")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
- }
- return NULL;
-}
-CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj)
-{
- if (pObj == NULL) {
- return NULL;
- }
- if (pObj->GetType() == PDFOBJ_NAME) {
- return _CSFromName(pObj->GetString());
- }
- if (pObj->GetType() == PDFOBJ_STREAM) {
- CPDF_Dictionary *pDict = ((CPDF_Stream *)pObj)->GetDict();
- if (!pDict) {
- return NULL;
- }
- CPDF_ColorSpace *pRet = NULL;
- FX_POSITION pos = pDict->GetStartPos();
- while (pos) {
- CFX_ByteString bsKey;
- CPDF_Object *pValue = pDict->GetNextElement(pos, bsKey);
- if (pValue->GetType() == PDFOBJ_NAME) {
- pRet = _CSFromName(pValue->GetString());
- }
- if (pRet) {
- return pRet;
- }
- }
- return NULL;
- }
- if (pObj->GetType() != PDFOBJ_ARRAY) {
- return NULL;
- }
- CPDF_Array* pArray = (CPDF_Array*)pObj;
- if (pArray->GetCount() == 0) {
- return NULL;
- }
- CFX_ByteString familyname = pArray->GetElementValue(0)->GetString();
- if (pArray->GetCount() == 1) {
- return _CSFromName(familyname);
- }
- CPDF_ColorSpace* pCS = NULL;
- FX_DWORD id = familyname.GetID();
- if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
- pCS = FX_NEW CPDF_CalGray();
- } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
- pCS = FX_NEW CPDF_CalRGB();
- } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
- pCS = FX_NEW CPDF_LabCS();
- } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
- pCS = FX_NEW CPDF_ICCBasedCS();
- } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || id == FXBSTR_ID('I', 0, 0, 0)) {
- pCS = FX_NEW CPDF_IndexedCS();
- } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
- pCS = FX_NEW CPDF_SeparationCS();
- } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
- pCS = FX_NEW CPDF_DeviceNCS();
- } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
- pCS = FX_NEW CPDF_PatternCS();
- } else {
- return NULL;
- }
- pCS->m_pDocument = pDoc;
- pCS->m_pArray = pArray;
- if (!pCS->v_Load(pDoc, pArray)) {
- pCS->ReleaseCS();
- return NULL;
- }
- return pCS;
-}
-CPDF_ColorSpace::CPDF_ColorSpace()
-{
- m_Family = 0;
- m_pArray = NULL;
- m_dwStdConversion = 0;
- m_pDocument = NULL;
-}
-void CPDF_ColorSpace::ReleaseCS()
-{
- if (this == GetStockCS(PDFCS_DEVICERGB)) {
- return;
- }
- if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
- return;
- }
- if (this == GetStockCS(PDFCS_DEVICECMYK)) {
- return;
- }
- if (this == GetStockCS(PDFCS_PATTERN)) {
- return;
- }
- delete this;
-}
-int CPDF_ColorSpace::GetBufSize() const
-{
- if (m_Family == PDFCS_PATTERN) {
- return sizeof(PatternValue);
- }
- return m_nComponents * sizeof(FX_FLOAT);
-}
-FX_FLOAT* CPDF_ColorSpace::CreateBuf()
-{
- int size = GetBufSize();
- FX_BYTE* pBuf = FX_Alloc(FX_BYTE, size);
- FXSYS_memset32(pBuf, 0, size);
- return (FX_FLOAT*)pBuf;
-}
-FX_BOOL CPDF_ColorSpace::sRGB() const
-{
- if (m_Family == PDFCS_DEVICERGB) {
- return TRUE;
- }
- if (m_Family != PDFCS_ICCBASED) {
- return FALSE;
- }
- CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
- return pCS->m_pProfile->m_bsRGB;
-}
-FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const
-{
- if (v_GetCMYK(pBuf, c, m, y, k)) {
- return TRUE;
- }
- FX_FLOAT R, G, B;
- if (!GetRGB(pBuf, R, G, B)) {
- return FALSE;
- }
- sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
- return TRUE;
-}
-FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const
-{
- if (v_SetCMYK(pBuf, c, m, y, k)) {
- return TRUE;
- }
- FX_FLOAT R, G, B;
- AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
- return SetRGB(pBuf, R, G, B);
-}
-void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const
-{
- if (buf == NULL || m_Family == PDFCS_PATTERN) {
- return;
- }
- FX_FLOAT min, max;
- for (int i = 0; i < m_nComponents; i ++) {
- GetDefaultValue(i, buf[i], min, max);
- }
-}
-int CPDF_ColorSpace::GetMaxIndex() const
-{
- if (m_Family != PDFCS_INDEXED) {
- return 0;
- }
- CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
- return pCS->m_MaxIndex;
-}
-void CPDF_ColorSpace::TranslateImageLine(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
-{
- CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
- FX_FLOAT* src = srcbuf;
- FX_FLOAT R, G, B;
- for (int i = 0; i < pixels; i ++) {
- for (int j = 0; j < m_nComponents; j ++)
- if (m_Family == PDFCS_INDEXED) {
- src[j] = (FX_FLOAT)(*src_buf ++);
- } else {
- src[j] = (FX_FLOAT)(*src_buf ++) / 255;
- }
- GetRGB(src, R, G, B);
- *dest_buf ++ = (FX_INT32)(B * 255);
- *dest_buf ++ = (FX_INT32)(G * 255);
- *dest_buf ++ = (FX_INT32)(R * 255);
- }
-}
-void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled)
-{
- if (bEnabled) {
- m_dwStdConversion ++;
- } else if (m_dwStdConversion) {
- m_dwStdConversion --;
- }
-}
-CPDF_Color::CPDF_Color(int family)
-{
- m_pCS = CPDF_ColorSpace::GetStockCS(family);
- int nComps = 3;
- if (family == PDFCS_DEVICEGRAY) {
- nComps = 1;
- } else if (family == PDFCS_DEVICECMYK) {
- nComps = 4;
- }
- m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
- for (int i = 0; i < nComps; i ++) {
- m_pBuffer[i] = 0;
- }
-}
-CPDF_Color::~CPDF_Color()
-{
- ReleaseBuffer();
- ReleaseColorSpace();
-}
-void CPDF_Color::ReleaseBuffer()
-{
- if (!m_pBuffer) {
- return;
- }
- if (m_pCS->GetFamily() == PDFCS_PATTERN) {
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- CPDF_Pattern* pPattern = pvalue->m_pPattern;
- if (pPattern && pPattern->m_pDocument) {
- pPattern->m_pDocument->GetPageData()->ReleasePattern(pPattern->m_pPatternObj);
- }
- }
- FX_Free(m_pBuffer);
- m_pBuffer = NULL;
-}
-void CPDF_Color::ReleaseColorSpace()
-{
- if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
- m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
- m_pCS = NULL;
- }
-}
-void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS)
-{
- if (m_pCS == pCS) {
- if (m_pBuffer == NULL) {
- m_pBuffer = pCS->CreateBuf();
- }
- ReleaseColorSpace();
- m_pCS = pCS;
- return;
- }
- ReleaseBuffer();
- ReleaseColorSpace();
- m_pCS = pCS;
- if (m_pCS) {
- m_pBuffer = pCS->CreateBuf();
- pCS->GetDefaultColor(m_pBuffer);
- }
-}
-void CPDF_Color::SetValue(FX_FLOAT* comps)
-{
- if (m_pBuffer == NULL) {
- return;
- }
- if (m_pCS->GetFamily() != PDFCS_PATTERN) {
- FXSYS_memcpy32(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
- }
-}
-void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps)
-{
- if (ncomps > MAX_PATTERN_COLORCOMPS) {
- return;
- }
- if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
- if (m_pBuffer) {
- FX_Free(m_pBuffer);
- }
- m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
- m_pBuffer = m_pCS->CreateBuf();
- }
- CPDF_DocPageData* pDocPageData = NULL;
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
- pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
- pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
- }
- pvalue->m_nComps = ncomps;
- pvalue->m_pPattern = pPattern;
- if (ncomps) {
- FXSYS_memcpy32(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
- }
-}
-void CPDF_Color::Copy(const CPDF_Color* pSrc)
-{
- ReleaseBuffer();
- ReleaseColorSpace();
- m_pCS = pSrc->m_pCS;
- if (m_pCS && m_pCS->m_pDocument) {
- CPDF_Array* pArray = m_pCS->GetArray();
- if (pArray) {
- m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
- }
- }
- if (m_pCS == NULL) {
- return;
- }
- m_pBuffer = m_pCS->CreateBuf();
- FXSYS_memcpy32(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
- if (m_pCS->GetFamily() == PDFCS_PATTERN) {
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
- pvalue->m_pPattern = pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(pvalue->m_pPattern->m_pPatternObj, FALSE, &pvalue->m_pPattern->m_ParentMatrix);
- }
- }
-}
-FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const
-{
- if (m_pCS == NULL || m_pBuffer == NULL) {
- return FALSE;
- }
- FX_FLOAT r, g, b;
- if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
- return FALSE;
- }
- R = (FX_INT32)(r * 255 + 0.5f);
- G = (FX_INT32)(g * 255 + 0.5f);
- B = (FX_INT32)(b * 255 + 0.5f);
- return TRUE;
-}
-CPDF_Pattern* CPDF_Color::GetPattern() const
-{
- if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- return pvalue->m_pPattern;
-}
-CPDF_ColorSpace* CPDF_Color::GetPatternCS() const
-{
- if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- return m_pCS->GetBaseCS();
-}
-FX_FLOAT* CPDF_Color::GetPatternColor() const
-{
- if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- return pvalue->m_nComps ? pvalue->m_Comps : NULL;
-}
-FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const
-{
- if (m_pCS != other.m_pCS || m_pCS == NULL) {
- return FALSE;
- }
- return FXSYS_memcmp32(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fxcodec/fx_codec.h" +#include "pageint.h" +#include <limits.h> +void sRGB_to_AdobeCMYK(FX_FLOAT R, FX_FLOAT G, FX_FLOAT B, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) +{ + c = 1.0f - R; + m = 1.0f - G; + y = 1.0f - B; + k = c; + if (m < k) { + k = m; + } + if (y < k) { + k = y; + } +} +CPDF_DeviceCS::CPDF_DeviceCS(int family) +{ + m_Family = family; + if (m_Family == PDFCS_DEVICERGB) { + m_nComponents = 3; + } else if (m_Family == PDFCS_DEVICEGRAY) { + m_nComponents = 1; + } else { + m_nComponents = 4; + } +} +FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + if (m_Family == PDFCS_DEVICERGB) { + R = pBuf[0]; + if (R < 0) { + R = 0; + } else if (R > 1) { + R = 1; + } + G = pBuf[1]; + if (G < 0) { + G = 0; + } else if (G > 1) { + G = 1; + } + B = pBuf[2]; + if (B < 0) { + B = 0; + } else if (B > 1) { + B = 1; + } + } else if (m_Family == PDFCS_DEVICEGRAY) { + R = *pBuf; + if (R < 0) { + R = 0; + } else if (R > 1) { + R = 1; + } + G = B = R; + } else if (m_Family == PDFCS_DEVICECMYK) { + if (!m_dwStdConversion) { + AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B); + } else { + FX_FLOAT k = pBuf[3]; + R = 1.0f - FX_MIN(1.0f, pBuf[0] + k); + G = 1.0f - FX_MIN(1.0f, pBuf[1] + k); + B = 1.0f - FX_MIN(1.0f, pBuf[2] + k); + } + } else { + ASSERT(m_Family == PDFCS_PATTERN); + R = G = B = 0; + return FALSE; + } + return TRUE; +} +FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const +{ + if (m_Family != PDFCS_DEVICECMYK) { + return FALSE; + } + c = pBuf[0]; + m = pBuf[1]; + y = pBuf[2]; + k = pBuf[3]; + return TRUE; +} +FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const +{ + if (m_Family == PDFCS_DEVICERGB) { + pBuf[0] = R; + pBuf[1] = G; + pBuf[2] = B; + return TRUE; + } else if (m_Family == PDFCS_DEVICEGRAY) { + if (R == G && R == B) { + *pBuf = R; + return TRUE; + } else { + return FALSE; + } + } else if (m_Family == PDFCS_DEVICECMYK) { + sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]); + return TRUE; + } + return FALSE; +} +FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const +{ + if (m_Family == PDFCS_DEVICERGB) { + AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]); + return TRUE; + } else if (m_Family == PDFCS_DEVICEGRAY) { + return FALSE; + } else if (m_Family == PDFCS_DEVICECMYK) { + pBuf[0] = c; + pBuf[1] = m; + pBuf[2] = y; + pBuf[3] = k; + return TRUE; + } + return FALSE; +} +static void ReverseRGB(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels) +{ + if (pDestBuf == pSrcBuf) + for (int i = 0; i < pixels; i ++) { + FX_BYTE temp = pDestBuf[2]; + pDestBuf[2] = pDestBuf[0]; + pDestBuf[0] = temp; + pDestBuf += 3; + } + else + for (int i = 0; i < pixels; i ++) { + *pDestBuf ++ = pSrcBuf[2]; + *pDestBuf ++ = pSrcBuf[1]; + *pDestBuf ++ = pSrcBuf[0]; + pSrcBuf += 3; + } +} +void CPDF_DeviceCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + if (bTransMask && m_Family == PDFCS_DEVICECMYK) { + for (int i = 0; i < pixels; i ++) { + int k = 255 - pSrcBuf[3]; + pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255; + pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255; + pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255; + pDestBuf += 3; + pSrcBuf += 4; + } + return; + } + if (m_Family == PDFCS_DEVICERGB) { + ReverseRGB(pDestBuf, pSrcBuf, pixels); + } else if (m_Family == PDFCS_DEVICEGRAY) { + for (int i = 0; i < pixels; i ++) { + *pDestBuf ++ = pSrcBuf[i]; + *pDestBuf ++ = pSrcBuf[i]; + *pDestBuf ++ = pSrcBuf[i]; + } + } else { + for (int i = 0; i < pixels; i ++) { + if (!m_dwStdConversion) { + AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3], pDestBuf[2], pDestBuf[1], pDestBuf[0]); + } else { + FX_BYTE k = pSrcBuf[3]; + pDestBuf[2] = 255 - FX_MIN(255, pSrcBuf[0] + k); + pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k); + pDestBuf[0] = 255 - FX_MIN(255, pSrcBuf[2] + k); + } + pSrcBuf += 4; + pDestBuf += 3; + } + } +} +const FX_BYTE g_sRGBSamples1[] = { + 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, 32, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 61, + 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, + 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76, 77, 77, 78, 78, 79, + 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 85, 86, + 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 91, 91, 91, 92, 92, 93, + 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 97, 97, 98, 98, 98, 99, + 99, 99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, + 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, + 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, + 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120, +}; +const FX_BYTE g_sRGBSamples2[] = { + 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151, + 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164, + 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176, + 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187, + 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, + 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, + 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, + 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, + 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, + 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, + 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, +}; +static void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) +{ + FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z; + FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z; + FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z; + if (R1 > 1) { + R1 = 1; + } + if (R1 < 0) { + R1 = 0; + } + if (G1 > 1) { + G1 = 1; + } + if (G1 < 0) { + G1 = 0; + } + if (B1 > 1) { + B1 = 1; + } + if (B1 < 0) { + B1 = 0; + } + int scale = (int)(R1 * 1023); + if (scale < 0) { + scale = 0; + } + if (scale < 192) { + R = (g_sRGBSamples1[scale] / 255.0f); + } else { + R = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); + } + scale = (int)(G1 * 1023); + if (scale < 0) { + scale = 0; + } + if (scale < 192) { + G = (g_sRGBSamples1[scale] / 255.0f); + } else { + G = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); + } + scale = (int)(B1 * 1023); + if (scale < 0) { + scale = 0; + } + if (scale < 192) { + B = (g_sRGBSamples1[scale] / 255.0f); + } else { + B = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); + } +} +class CPDF_CalGray : public CPDF_ColorSpace +{ +public: + CPDF_CalGray(); + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const; + FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const; + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Gamma; +}; +CPDF_CalGray::CPDF_CalGray() +{ + m_Family = PDFCS_CALGRAY; + m_nComponents = 1; +} +FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Dictionary* pDict = pArray->GetDict(1); + CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint")); + int i; + for (i = 0; i < 3; i ++) { + m_WhitePoint[i] = pParam->GetNumber(i); + } + pParam = pDict->GetArray(FX_BSTRC("BlackPoint")); + for (i = 0; i < 3; i ++) { + m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0; + } + m_Gamma = pDict->GetNumber(FX_BSTRC("Gamma")); + if (m_Gamma == 0) { + m_Gamma = 1.0f; + } + return TRUE; +} +FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + R = G = B = *pBuf; + return TRUE; +} +FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const +{ + if (R == G && R == B) { + *pBuf = R; + return TRUE; + } else { + return FALSE; + } +} +void CPDF_CalGray::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + for (int i = 0; i < pixels; i ++) { + *pDestBuf ++ = pSrcBuf[i]; + *pDestBuf ++ = pSrcBuf[i]; + *pDestBuf ++ = pSrcBuf[i]; + } +} +class CPDF_CalRGB : public CPDF_ColorSpace +{ +public: + CPDF_CalRGB(); + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const; + FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const; + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Gamma[3]; + FX_FLOAT m_Matrix[9]; + FX_BOOL m_bGamma, m_bMatrix; +}; +CPDF_CalRGB::CPDF_CalRGB() +{ + m_Family = PDFCS_CALRGB; + m_nComponents = 3; +} +FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Dictionary* pDict = pArray->GetDict(1); + CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint")); + int i; + for (i = 0; i < 3; i ++) { + m_WhitePoint[i] = pParam->GetNumber(i); + } + pParam = pDict->GetArray(FX_BSTRC("BlackPoint")); + for (i = 0; i < 3; i ++) { + m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0; + } + pParam = pDict->GetArray(FX_BSTRC("Gamma")); + if (pParam) { + m_bGamma = TRUE; + for (i = 0; i < 3; i ++) { + m_Gamma[i] = pParam->GetNumber(i); + } + } else { + m_bGamma = FALSE; + } + pParam = pDict->GetArray(FX_BSTRC("Matrix")); + if (pParam) { + m_bMatrix = TRUE; + for (i = 0; i < 9; i ++) { + m_Matrix[i] = pParam->GetNumber(i); + } + } else { + m_bMatrix = FALSE; + } + return TRUE; +} +FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + FX_FLOAT A_ = pBuf[0]; + FX_FLOAT B_ = pBuf[1]; + FX_FLOAT C_ = pBuf[2]; + if (m_bGamma) { + A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]); + B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]); + C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]); + } + FX_FLOAT X, Y, Z; + if (m_bMatrix) { + X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_; + Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_; + Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_; + } else { + X = A_; + Y = B_; + Z = C_; + } + XYZ_to_sRGB(X, Y, Z, R, G, B); + return TRUE; +} +FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const +{ + pBuf[0] = R; + pBuf[1] = G; + pBuf[2] = B; + return TRUE; +} +void CPDF_CalRGB::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + if (bTransMask) { + FX_FLOAT Cal[3]; + FX_FLOAT R, G, B; + for(int i = 0; i < pixels; i ++) { + Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255; + Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255; + Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255; + GetRGB(Cal, R, G, B); + pDestBuf[0] = FXSYS_round(B * 255); + pDestBuf[1] = FXSYS_round(G * 255); + pDestBuf[2] = FXSYS_round(R * 255); + pSrcBuf += 3; + pDestBuf += 3; + } + } + ReverseRGB(pDestBuf, pSrcBuf, pixels); +} +class CPDF_LabCS : public CPDF_ColorSpace +{ +public: + CPDF_LabCS() + { + m_Family = PDFCS_LAB; + m_nComponents = 3; + } + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const; + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const; + virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const; + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Ranges[4]; +}; +FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Dictionary* pDict = pArray->GetDict(1); + CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint")); + int i; + for (i = 0; i < 3; i ++) { + m_WhitePoint[i] = pParam->GetNumber(i); + } + pParam = pDict->GetArray(FX_BSTRC("BlackPoint")); + for (i = 0; i < 3; i ++) { + m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0; + } + pParam = pDict->GetArray(FX_BSTRC("Range")); + const FX_FLOAT def_ranges[4] = { -100 * 1.0f, 100 * 1.0f, -100 * 1.0f, 100 * 1.0f}; + for (i = 0; i < 4; i ++) { + m_Ranges[i] = pParam ? pParam->GetNumber(i) : def_ranges[i]; + } + return TRUE; +} +void CPDF_LabCS::GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const +{ + value = 0; + if (iComponent == 0) { + min = 0; + max = 100 * 1.0f; + } else { + min = m_Ranges[iComponent * 2 - 2]; + max = m_Ranges[iComponent * 2 - 1]; + if (value < min) { + value = min; + } else if (value > max) { + value = max; + } + } +} +FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + FX_FLOAT Lstar = pBuf[0]; + FX_FLOAT astar = pBuf[1]; + FX_FLOAT bstar = pBuf[2]; + FX_FLOAT M = (Lstar + 16.0f) / 116.0f; + FX_FLOAT L = M + astar / 500.0f; + FX_FLOAT N = M - bstar / 200.0f; + FX_FLOAT X, Y, Z; + if (L < 0.2069f) { + X = 0.957f * 0.12842f * (L - 0.1379f); + } else { + X = 0.957f * L * L * L; + } + if (M < 0.2069f) { + Y = 0.12842f * (M - 0.1379f); + } else { + Y = M * M * M; + } + if (N < 0.2069f) { + Z = 1.0889f * 0.12842f * (N - 0.1379f); + } else { + Z = 1.0889f * N * N * N; + } + XYZ_to_sRGB(X, Y, Z, R, G, B); + return TRUE; +} +FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const +{ + return FALSE; +} +void CPDF_LabCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + for (int i = 0; i < pixels; i ++) { + FX_FLOAT lab[3]; + FX_FLOAT R, G, B; + lab[0] = (pSrcBuf[0] * 100 / 255.0f); + lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128); + lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128); + GetRGB(lab, R, G, B); + pDestBuf[0] = (FX_INT32)(B * 255); + pDestBuf[1] = (FX_INT32)(G * 255); + pDestBuf[2] = (FX_INT32)(R * 255); + pDestBuf += 3; + pSrcBuf += 3; + } +} +CPDF_IccProfile::CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents) +{ + m_bsRGB = nComponents == 3 && dwSize == 3144 && FXSYS_memcmp32(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0; + m_pTransform = NULL; + if (!m_bsRGB && CPDF_ModuleMgr::Get()->GetIccModule()) { + m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(pData, dwSize, nComponents); + } +} +CPDF_IccProfile::~CPDF_IccProfile() +{ + if (m_pTransform) { + CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform); + } +} +class CPDF_ICCBasedCS : public CPDF_ColorSpace +{ +public: + CPDF_ICCBasedCS(); + virtual ~CPDF_ICCBasedCS(); + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + void GetDefaultValue(int i, FX_FLOAT& min, FX_FLOAT& max) const + { + min = m_pRanges[i * 2]; + max = m_pRanges[i * 2 + 1]; + } + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const; + FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const; + virtual void EnableStdConversion(FX_BOOL bEnabled); + virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const; + FX_FLOAT* m_pRanges; + CPDF_IccProfile* m_pProfile; + CPDF_ColorSpace* m_pAlterCS; + FX_LPBYTE m_pCache; + FX_BOOL m_bOwn; +}; +CPDF_ICCBasedCS::CPDF_ICCBasedCS() +{ + m_pAlterCS = NULL; + m_pProfile = NULL; + m_Family = PDFCS_ICCBASED; + m_pCache = NULL; + m_pRanges = NULL; + m_bOwn = FALSE; +} +CPDF_ICCBasedCS::~CPDF_ICCBasedCS() +{ + if (m_pCache) { + FX_Free(m_pCache); + } + if (m_pRanges) { + FX_Free(m_pRanges); + } + if (m_pAlterCS && m_bOwn) { + m_pAlterCS->ReleaseCS(); + } + if (m_pProfile && m_pDocument) { + m_pDocument->GetPageData()->ReleaseIccProfile(NULL, m_pProfile); + } +} +FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Stream* pStream = pArray->GetStream(1); + if (pStream == NULL) { + return FALSE; + } + m_nComponents = pStream->GetDict()->GetInteger(FX_BSTRC("N")); + if (m_nComponents < 0 || m_nComponents > (1 << 16)) { + return FALSE; + } + CPDF_Array* pRanges = pStream->GetDict()->GetArray(FX_BSTRC("Range")); + m_pRanges = FX_Alloc(FX_FLOAT, m_nComponents * 2); + for (int i = 0; i < m_nComponents * 2; i ++) { + if (pRanges) { + m_pRanges[i] = pRanges->GetNumber(i); + } else if (i % 2) { + m_pRanges[i] = 1.0f; + } else { + m_pRanges[i] = 0; + } + } + m_pProfile = pDoc->LoadIccProfile(pStream, m_nComponents); + if (!m_pProfile) { + return FALSE; + } + if (m_pProfile->m_pTransform == NULL) { + CPDF_Object* pAlterCSObj = pStream->GetDict()->GetElementValue(FX_BSTRC("Alternate")); + if (pAlterCSObj) { + CPDF_ColorSpace* alter_cs = CPDF_ColorSpace::Load(pDoc, pAlterCSObj); + if (alter_cs) { + if (alter_cs->CountComponents() > m_nComponents) { + alter_cs->ReleaseCS(); + } else { + m_pAlterCS = alter_cs; + m_bOwn = TRUE; + } + } + } + if (!m_pAlterCS) { + if (m_nComponents == 3) { + m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); + } else if (m_nComponents == 4) { + m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); + } else { + m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); + } + } + } + return TRUE; +} +FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + if (m_pProfile && m_pProfile->m_bsRGB) { + R = pBuf[0]; + G = pBuf[1]; + B = pBuf[2]; + return TRUE; + } + ICodec_IccModule *pIccModule = CPDF_ModuleMgr::Get()->GetIccModule(); + if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) { + if (m_pAlterCS) { + m_pAlterCS->GetRGB(pBuf, R, G, B); + } else { + R = G = B = 0.0f; + } + return TRUE; + } + FX_FLOAT rgb[3]; + pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb); + R = rgb[0]; + G = rgb[1]; + B = rgb[2]; + return TRUE; +} +FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const +{ + if (m_nComponents != 4) { + return FALSE; + } + c = pBuf[0]; + m = pBuf[1]; + y = pBuf[2]; + k = pBuf[3]; + return TRUE; +} +FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const +{ + return FALSE; +} +void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) +{ + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAlterCS) { + m_pAlterCS->EnableStdConversion(bEnabled); + } +} +void CPDF_ICCBasedCS::TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + if (m_pProfile->m_bsRGB) { + ReverseRGB(pDestBuf, pSrcBuf, pixels); + } else if (m_pProfile->m_pTransform) { + int nMaxColors = 1; + for (int i = 0; i < m_nComponents; i ++) { + nMaxColors *= 52; + } + if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) { + CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels); + } else { + if (m_pCache == NULL) { + ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc(FX_BYTE, nMaxColors * 3); + FX_LPBYTE temp_src = FX_Alloc(FX_BYTE, nMaxColors * m_nComponents); + FX_LPBYTE pSrc = temp_src; + for (int i = 0; i < nMaxColors; i ++) { + FX_DWORD color = i; + FX_DWORD order = nMaxColors / 52; + for (int c = 0; c < m_nComponents; c ++) { + *pSrc++ = (FX_BYTE)(color / order * 5); + color %= order; + order /= 52; + } + } + CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors); + FX_Free(temp_src); + } + for (int i = 0; i < pixels; i ++) { + int index = 0; + for (int c = 0; c < m_nComponents; c ++) { + index = index * 52 + (*pSrcBuf) / 5; + pSrcBuf ++; + } + index *= 3; + *pDestBuf++ = m_pCache[index]; + *pDestBuf++ = m_pCache[index + 1]; + *pDestBuf++ = m_pCache[index + 2]; + } + } + } else if (m_pAlterCS) { + m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, image_height); + } +} +class CPDF_IndexedCS : public CPDF_ColorSpace +{ +public: + CPDF_IndexedCS(); + virtual ~CPDF_IndexedCS(); + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + void GetDefaultValue(int iComponent, FX_FLOAT& min, FX_FLOAT& max) const + { + min = 0; + max = (FX_FLOAT)m_MaxIndex; + } + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual CPDF_ColorSpace* GetBaseCS() const + { + return m_pBaseCS; + } + virtual void EnableStdConversion(FX_BOOL bEnabled); + CPDF_ColorSpace* m_pBaseCS; + int m_nBaseComponents; + int m_MaxIndex; + CFX_ByteString m_Table; + FX_FLOAT* m_pCompMinMax; +}; +CPDF_IndexedCS::CPDF_IndexedCS() +{ + m_pBaseCS = NULL; + m_Family = PDFCS_INDEXED; + m_nComponents = 1; + m_pCompMinMax = NULL; +} +CPDF_IndexedCS::~CPDF_IndexedCS() +{ + if (m_pCompMinMax) { + FX_Free(m_pCompMinMax); + } + CPDF_ColorSpace* pCS = m_pBaseCS; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } +} +FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + if (pArray->GetCount() < 4) { + return FALSE; + } + CPDF_Object* pBaseObj = pArray->GetElementValue(1); + if (pBaseObj == m_pArray) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); + m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL); + if (m_pBaseCS == NULL) { + return FALSE; + } + m_nBaseComponents = m_pBaseCS->CountComponents(); + m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2); + FX_FLOAT defvalue; + for (int i = 0; i < m_nBaseComponents; i ++) { + m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMinMax[i * 2 + 1]); + m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; + } + m_MaxIndex = pArray->GetInteger(2); + CPDF_Object* pTableObj = pArray->GetElementValue(3); + if (pTableObj == NULL) { + return FALSE; + } + FX_LPCBYTE pTable = NULL; + FX_DWORD size = 0; + CPDF_StreamAcc* pStreamAcc = NULL; + if (pTableObj->GetType() == PDFOBJ_STRING) { + m_Table = ((CPDF_String*)pTableObj)->GetString(); + } else if (pTableObj->GetType() == PDFOBJ_STREAM) { + CPDF_StreamAcc acc; + acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE); + m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize()); + } + return TRUE; +} +FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + int index = (FX_INT32)(*pBuf); + if (index < 0 || index > m_MaxIndex) { + return FALSE; + } + if (m_nBaseComponents) { + if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents || + (index + 1)*m_nBaseComponents > (int)m_Table.GetLength()) { + R = G = B = 0; + return FALSE; + } + } + CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents); + FX_FLOAT* comps = Comps; + FX_LPCBYTE pTable = m_Table; + for (int i = 0; i < m_nBaseComponents; i ++) { + comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255; + } + m_pBaseCS->GetRGB(comps, R, G, B); + return TRUE; +} +void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) +{ + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pBaseCS) { + m_pBaseCS->EnableStdConversion(bEnabled); + } +} +#define MAX_PATTERN_COLORCOMPS 16 +typedef struct _PatternValue { + CPDF_Pattern* m_pPattern; + int m_nComps; + FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS]; +} PatternValue; +CPDF_PatternCS::CPDF_PatternCS() +{ + m_Family = PDFCS_PATTERN; + m_pBaseCS = NULL; + m_nComponents = 1; +} +CPDF_PatternCS::~CPDF_PatternCS() +{ + CPDF_ColorSpace* pCS = m_pBaseCS; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } +} +FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Object* pBaseCS = pArray->GetElementValue(1); + if (pBaseCS == m_pArray) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); + m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL); + if (m_pBaseCS) { + m_nComponents = m_pBaseCS->CountComponents() + 1; + if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) { + return FALSE; + } + } else { + m_nComponents = 1; + } + return TRUE; +} +FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + if (m_pBaseCS) { + PatternValue* pvalue = (PatternValue*)pBuf; + m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B); + return TRUE; + } + R = G = B = 0.75f; + return FALSE; +} +class CPDF_SeparationCS : public CPDF_ColorSpace +{ +public: + CPDF_SeparationCS(); + virtual ~CPDF_SeparationCS(); + virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const + { + value = 1.0f; + min = 0; + max = 1.0f; + } + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual void EnableStdConversion(FX_BOOL bEnabled); + CPDF_ColorSpace* m_pAltCS; + CPDF_Function* m_pFunc; + enum {None, All, Colorant} m_Type; +}; +CPDF_SeparationCS::CPDF_SeparationCS() +{ + m_Family = PDFCS_SEPARATION; + m_pAltCS = NULL; + m_pFunc = NULL; + m_nComponents = 1; +} +CPDF_SeparationCS::~CPDF_SeparationCS() +{ + if (m_pAltCS) { + m_pAltCS->ReleaseCS(); + } + if (m_pFunc) { + delete m_pFunc; + } +} +FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CFX_ByteString name = pArray->GetString(1); + if (name == FX_BSTRC("None")) { + m_Type = None; + } else { + m_Type = Colorant; + CPDF_Object* pAltCS = pArray->GetElementValue(2); + if (pAltCS == m_pArray) { + return FALSE; + } + m_pAltCS = Load(pDoc, pAltCS); + CPDF_Object* pFuncObj = pArray->GetElementValue(3); + if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) { + m_pFunc = CPDF_Function::Load(pFuncObj); + } + if (m_pFunc && m_pAltCS && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { + delete m_pFunc; + m_pFunc = NULL; + } + } + return TRUE; +} +FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + if (m_Type == None) { + return FALSE; + } + if (m_pFunc == NULL) { + if (m_pAltCS == NULL) { + return FALSE; + } + int nComps = m_pAltCS->CountComponents(); + CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps); + for (int i = 0; i < nComps; i ++) { + results[i] = *pBuf; + } + m_pAltCS->GetRGB(results, R, G, B); + return TRUE; + } + CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs()); + int nresults; + m_pFunc->Call(pBuf, 1, results, nresults); + if (nresults == 0) { + return FALSE; + } + if (m_pAltCS) { + m_pAltCS->GetRGB(results, R, G, B); + return TRUE; + } else { + R = G = B = 0; + return FALSE; + } +} +void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) +{ + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAltCS) { + m_pAltCS->EnableStdConversion(bEnabled); + } +} +class CPDF_DeviceNCS : public CPDF_ColorSpace +{ +public: + CPDF_DeviceNCS(); + virtual ~CPDF_DeviceNCS(); + virtual void GetDefaultValue(int iComponent, FX_FLOAT& value, FX_FLOAT& min, FX_FLOAT& max) const + { + value = 1.0f; + min = 0; + max = 1.0f; + } + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual void EnableStdConversion(FX_BOOL bEnabled); + CPDF_ColorSpace* m_pAltCS; + CPDF_Function* m_pFunc; +}; +CPDF_DeviceNCS::CPDF_DeviceNCS() +{ + m_Family = PDFCS_DEVICEN; + m_pAltCS = NULL; + m_pFunc = NULL; +} +CPDF_DeviceNCS::~CPDF_DeviceNCS() +{ + if (m_pFunc) { + delete m_pFunc; + } + if (m_pAltCS) { + m_pAltCS->ReleaseCS(); + } +} +FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) +{ + CPDF_Object* pObj = pArray->GetElementValue(1); + if (!pObj) { + return FALSE; + } + if (pObj->GetType() != PDFOBJ_ARRAY) { + return FALSE; + } + m_nComponents = ((CPDF_Array*)pObj)->GetCount(); + CPDF_Object* pAltCS = pArray->GetElementValue(2); + if (!pAltCS || pAltCS == m_pArray) { + return FALSE; + } + m_pAltCS = Load(pDoc, pAltCS); + m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3)); + if (m_pAltCS == NULL || m_pFunc == NULL) { + return FALSE; + } + if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { + return FALSE; + } + return TRUE; +} +FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const +{ + if (m_pFunc == NULL) { + return FALSE; + } + CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs()); + int nresults; + m_pFunc->Call(pBuf, m_nComponents, results, nresults); + if (nresults == 0) { + return FALSE; + } + m_pAltCS->GetRGB(results, R, G, B); + return TRUE; +} +void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) +{ + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAltCS) { + m_pAltCS->EnableStdConversion(bEnabled); + } +} +CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) +{ + return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);; +} +CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) +{ + if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + } + if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + } + if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + } + if (name == FX_BSTRC("Pattern")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + } + return NULL; +} +CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) +{ + if (pObj == NULL) { + return NULL; + } + if (pObj->GetType() == PDFOBJ_NAME) { + return _CSFromName(pObj->GetString()); + } + if (pObj->GetType() == PDFOBJ_STREAM) { + CPDF_Dictionary *pDict = ((CPDF_Stream *)pObj)->GetDict(); + if (!pDict) { + return NULL; + } + CPDF_ColorSpace *pRet = NULL; + FX_POSITION pos = pDict->GetStartPos(); + while (pos) { + CFX_ByteString bsKey; + CPDF_Object *pValue = pDict->GetNextElement(pos, bsKey); + if (pValue->GetType() == PDFOBJ_NAME) { + pRet = _CSFromName(pValue->GetString()); + } + if (pRet) { + return pRet; + } + } + return NULL; + } + if (pObj->GetType() != PDFOBJ_ARRAY) { + return NULL; + } + CPDF_Array* pArray = (CPDF_Array*)pObj; + if (pArray->GetCount() == 0) { + return NULL; + } + CFX_ByteString familyname = pArray->GetElementValue(0)->GetString(); + if (pArray->GetCount() == 1) { + return _CSFromName(familyname); + } + CPDF_ColorSpace* pCS = NULL; + FX_DWORD id = familyname.GetID(); + if (id == FXBSTR_ID('C', 'a', 'l', 'G')) { + pCS = FX_NEW CPDF_CalGray(); + } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) { + pCS = FX_NEW CPDF_CalRGB(); + } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) { + pCS = FX_NEW CPDF_LabCS(); + } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) { + pCS = FX_NEW CPDF_ICCBasedCS(); + } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || id == FXBSTR_ID('I', 0, 0, 0)) { + pCS = FX_NEW CPDF_IndexedCS(); + } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) { + pCS = FX_NEW CPDF_SeparationCS(); + } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) { + pCS = FX_NEW CPDF_DeviceNCS(); + } else if (id == FXBSTR_ID('P', 'a', 't', 't')) { + pCS = FX_NEW CPDF_PatternCS(); + } else { + return NULL; + } + pCS->m_pDocument = pDoc; + pCS->m_pArray = pArray; + if (!pCS->v_Load(pDoc, pArray)) { + pCS->ReleaseCS(); + return NULL; + } + return pCS; +} +CPDF_ColorSpace::CPDF_ColorSpace() +{ + m_Family = 0; + m_pArray = NULL; + m_dwStdConversion = 0; + m_pDocument = NULL; +} +void CPDF_ColorSpace::ReleaseCS() +{ + if (this == GetStockCS(PDFCS_DEVICERGB)) { + return; + } + if (this == GetStockCS(PDFCS_DEVICEGRAY)) { + return; + } + if (this == GetStockCS(PDFCS_DEVICECMYK)) { + return; + } + if (this == GetStockCS(PDFCS_PATTERN)) { + return; + } + delete this; +} +int CPDF_ColorSpace::GetBufSize() const +{ + if (m_Family == PDFCS_PATTERN) { + return sizeof(PatternValue); + } + return m_nComponents * sizeof(FX_FLOAT); +} +FX_FLOAT* CPDF_ColorSpace::CreateBuf() +{ + int size = GetBufSize(); + FX_BYTE* pBuf = FX_Alloc(FX_BYTE, size); + FXSYS_memset32(pBuf, 0, size); + return (FX_FLOAT*)pBuf; +} +FX_BOOL CPDF_ColorSpace::sRGB() const +{ + if (m_Family == PDFCS_DEVICERGB) { + return TRUE; + } + if (m_Family != PDFCS_ICCBASED) { + return FALSE; + } + CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this; + return pCS->m_pProfile->m_bsRGB; +} +FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const +{ + if (v_GetCMYK(pBuf, c, m, y, k)) { + return TRUE; + } + FX_FLOAT R, G, B; + if (!GetRGB(pBuf, R, G, B)) { + return FALSE; + } + sRGB_to_AdobeCMYK(R, G, B, c, m, y, k); + return TRUE; +} +FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const +{ + if (v_SetCMYK(pBuf, c, m, y, k)) { + return TRUE; + } + FX_FLOAT R, G, B; + AdobeCMYK_to_sRGB(c, m, y, k, R, G, B); + return SetRGB(pBuf, R, G, B); +} +void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const +{ + if (buf == NULL || m_Family == PDFCS_PATTERN) { + return; + } + FX_FLOAT min, max; + for (int i = 0; i < m_nComponents; i ++) { + GetDefaultValue(i, buf[i], min, max); + } +} +int CPDF_ColorSpace::GetMaxIndex() const +{ + if (m_Family != PDFCS_INDEXED) { + return 0; + } + CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this; + return pCS->m_MaxIndex; +} +void CPDF_ColorSpace::TranslateImageLine(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const +{ + CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents); + FX_FLOAT* src = srcbuf; + FX_FLOAT R, G, B; + for (int i = 0; i < pixels; i ++) { + for (int j = 0; j < m_nComponents; j ++) + if (m_Family == PDFCS_INDEXED) { + src[j] = (FX_FLOAT)(*src_buf ++); + } else { + src[j] = (FX_FLOAT)(*src_buf ++) / 255; + } + GetRGB(src, R, G, B); + *dest_buf ++ = (FX_INT32)(B * 255); + *dest_buf ++ = (FX_INT32)(G * 255); + *dest_buf ++ = (FX_INT32)(R * 255); + } +} +void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) +{ + if (bEnabled) { + m_dwStdConversion ++; + } else if (m_dwStdConversion) { + m_dwStdConversion --; + } +} +CPDF_Color::CPDF_Color(int family) +{ + m_pCS = CPDF_ColorSpace::GetStockCS(family); + int nComps = 3; + if (family == PDFCS_DEVICEGRAY) { + nComps = 1; + } else if (family == PDFCS_DEVICECMYK) { + nComps = 4; + } + m_pBuffer = FX_Alloc(FX_FLOAT, nComps); + for (int i = 0; i < nComps; i ++) { + m_pBuffer[i] = 0; + } +} +CPDF_Color::~CPDF_Color() +{ + ReleaseBuffer(); + ReleaseColorSpace(); +} +void CPDF_Color::ReleaseBuffer() +{ + if (!m_pBuffer) { + return; + } + if (m_pCS->GetFamily() == PDFCS_PATTERN) { + PatternValue* pvalue = (PatternValue*)m_pBuffer; + CPDF_Pattern* pPattern = pvalue->m_pPattern; + if (pPattern && pPattern->m_pDocument) { + pPattern->m_pDocument->GetPageData()->ReleasePattern(pPattern->m_pPatternObj); + } + } + FX_Free(m_pBuffer); + m_pBuffer = NULL; +} +void CPDF_Color::ReleaseColorSpace() +{ + if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) { + m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray()); + m_pCS = NULL; + } +} +void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) +{ + if (m_pCS == pCS) { + if (m_pBuffer == NULL) { + m_pBuffer = pCS->CreateBuf(); + } + ReleaseColorSpace(); + m_pCS = pCS; + return; + } + ReleaseBuffer(); + ReleaseColorSpace(); + m_pCS = pCS; + if (m_pCS) { + m_pBuffer = pCS->CreateBuf(); + pCS->GetDefaultColor(m_pBuffer); + } +} +void CPDF_Color::SetValue(FX_FLOAT* comps) +{ + if (m_pBuffer == NULL) { + return; + } + if (m_pCS->GetFamily() != PDFCS_PATTERN) { + FXSYS_memcpy32(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT)); + } +} +void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) +{ + if (ncomps > MAX_PATTERN_COLORCOMPS) { + return; + } + if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) { + if (m_pBuffer) { + FX_Free(m_pBuffer); + } + m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + m_pBuffer = m_pCS->CreateBuf(); + } + CPDF_DocPageData* pDocPageData = NULL; + PatternValue* pvalue = (PatternValue*)m_pBuffer; + if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) { + pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData(); + pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj); + } + pvalue->m_nComps = ncomps; + pvalue->m_pPattern = pPattern; + if (ncomps) { + FXSYS_memcpy32(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT)); + } +} +void CPDF_Color::Copy(const CPDF_Color* pSrc) +{ + ReleaseBuffer(); + ReleaseColorSpace(); + m_pCS = pSrc->m_pCS; + if (m_pCS && m_pCS->m_pDocument) { + CPDF_Array* pArray = m_pCS->GetArray(); + if (pArray) { + m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray); + } + } + if (m_pCS == NULL) { + return; + } + m_pBuffer = m_pCS->CreateBuf(); + FXSYS_memcpy32(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize()); + if (m_pCS->GetFamily() == PDFCS_PATTERN) { + PatternValue* pvalue = (PatternValue*)m_pBuffer; + if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) { + pvalue->m_pPattern = pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(pvalue->m_pPattern->m_pPatternObj, FALSE, &pvalue->m_pPattern->m_ParentMatrix); + } + } +} +FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const +{ + if (m_pCS == NULL || m_pBuffer == NULL) { + return FALSE; + } + FX_FLOAT r, g, b; + if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) { + return FALSE; + } + R = (FX_INT32)(r * 255 + 0.5f); + G = (FX_INT32)(g * 255 + 0.5f); + B = (FX_INT32)(b * 255 + 0.5f); + return TRUE; +} +CPDF_Pattern* CPDF_Color::GetPattern() const +{ + if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) { + return NULL; + } + PatternValue* pvalue = (PatternValue*)m_pBuffer; + return pvalue->m_pPattern; +} +CPDF_ColorSpace* CPDF_Color::GetPatternCS() const +{ + if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) { + return NULL; + } + return m_pCS->GetBaseCS(); +} +FX_FLOAT* CPDF_Color::GetPatternColor() const +{ + if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) { + return NULL; + } + PatternValue* pvalue = (PatternValue*)m_pBuffer; + return pvalue->m_nComps ? pvalue->m_Comps : NULL; +} +FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const +{ + if (m_pCS != other.m_pCS || m_pCS == NULL) { + return FALSE; + } + return FXSYS_memcmp32(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp index d4e5bef400..a9d2c4d695 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp @@ -1,647 +1,647 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fdrm/fx_crypt.h"
-#include "../fpdf_font/font_int.h"
-#include "pageint.h"
-class CPDF_PageModule : public CPDF_PageModuleDef
-{
-public:
- CPDF_PageModule() : m_StockGrayCS(PDFCS_DEVICEGRAY), m_StockRGBCS(PDFCS_DEVICERGB),
- m_StockCMYKCS(PDFCS_DEVICECMYK) {}
- virtual ~CPDF_PageModule() {}
- virtual FX_BOOL Installed()
- {
- return TRUE;
- }
- virtual CPDF_DocPageData* CreateDocData(CPDF_Document* pDoc)
- {
- return FX_NEW CPDF_DocPageData(pDoc);
- }
- virtual void ReleaseDoc(CPDF_Document* pDoc);
- virtual void ClearDoc(CPDF_Document* pDoc);
- virtual CPDF_FontGlobals* GetFontGlobals()
- {
- return &m_FontGlobals;
- }
- virtual void ClearStockFont(CPDF_Document* pDoc)
- {
- m_FontGlobals.Clear(pDoc);
- }
- virtual CPDF_ColorSpace* GetStockCS(int family);
- virtual void NotifyCJKAvailable();
- CPDF_FontGlobals m_FontGlobals;
- CPDF_DeviceCS m_StockGrayCS;
- CPDF_DeviceCS m_StockRGBCS;
- CPDF_DeviceCS m_StockCMYKCS;
- CPDF_PatternCS m_StockPatternCS;
-};
-CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family)
-{
- if (family == PDFCS_DEVICEGRAY) {
- return &m_StockGrayCS;
- }
- if (family == PDFCS_DEVICERGB) {
- return &m_StockRGBCS;
- }
- if (family == PDFCS_DEVICECMYK) {
- return &m_StockCMYKCS;
- }
- if (family == PDFCS_PATTERN) {
- return &m_StockPatternCS;
- }
- return NULL;
-}
-void CPDF_ModuleMgr::InitPageModule()
-{
- if (m_pPageModule) {
- delete m_pPageModule;
- }
- CPDF_PageModule* pPageModule = FX_NEW CPDF_PageModule;
- m_pPageModule = pPageModule;
-}
-void CPDF_PageModule::ReleaseDoc(CPDF_Document* pDoc)
-{
- delete pDoc->GetPageData();
-}
-void CPDF_PageModule::ClearDoc(CPDF_Document* pDoc)
-{
- pDoc->GetPageData()->Clear(FALSE);
-}
-void CPDF_PageModule::NotifyCJKAvailable()
-{
- m_FontGlobals.m_CMapManager.ReloadAll();
-}
-CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict)
-{
- if (!pFontDict) {
- return NULL;
- }
- return GetValidatePageData()->GetFont(pFontDict, FALSE);
-}
-CPDF_Font* CPDF_Document::FindFont(CPDF_Dictionary* pFontDict)
-{
- if (!pFontDict) {
- return NULL;
- }
- return GetValidatePageData()->GetFont(pFontDict, TRUE);
-}
-CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream)
-{
- if (pStream == NULL) {
- return NULL;
- }
- return GetValidatePageData()->GetFontFileStreamAcc(pStream);
-}
-CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name);
-CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources)
-{
- return GetValidatePageData()->GetColorSpace(pCSObj, pResources);
-}
-CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix)
-{
- return GetValidatePageData()->GetPattern(pPatternObj, bShading, matrix);
-}
-CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents)
-{
- return GetValidatePageData()->GetIccProfile(pStream, nComponents);
-}
-CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj)
-{
- if (!pObj) {
- return NULL;
- }
- FXSYS_assert(pObj->GetObjNum());
- return GetValidatePageData()->GetImage(pObj);
-}
-void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj)
-{
- if (!pCSObj) {
- return;
- }
- GetPageData()->ReleaseColorSpace(pCSObj);
-}
-CPDF_DocPageData::CPDF_DocPageData(CPDF_Document *pPDFDoc)
- : m_pPDFDoc(pPDFDoc)
- , m_FontMap()
- , m_ColorSpaceMap()
- , m_PatternMap()
- , m_ImageMap()
- , m_IccProfileMap()
- , m_FontFileMap()
-{
- m_FontMap.InitHashTable(64);
- m_ColorSpaceMap.InitHashTable(32);
- m_PatternMap.InitHashTable(16);
- m_ImageMap.InitHashTable(64);
- m_IccProfileMap.InitHashTable(16);
- m_FontFileMap.InitHashTable(32);
-}
-CPDF_DocPageData::~CPDF_DocPageData()
-{
- Clear(FALSE);
- Clear(TRUE);
- FX_POSITION pos = NULL;
-}
-void CPDF_DocPageData::Clear(FX_BOOL bRelease)
-{
- FX_POSITION pos;
- FX_DWORD nCount;
- {
- pos = m_PatternMap.GetStartPosition();
- while (pos) {
- CPDF_Object* ptObj;
- CPDF_CountedObject<CPDF_Pattern*>* ptData;
- m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
- nCount = ptData->m_nCount;
- if (bRelease || nCount < 2) {
- delete ptData->m_Obj;
- ptData->m_Obj = NULL;
- }
- }
- }
- {
- pos = m_FontMap.GetStartPosition();
- while (pos) {
- CPDF_Dictionary* fontDict;
- CPDF_CountedObject<CPDF_Font*>* fontData;
- m_FontMap.GetNextAssoc(pos, fontDict, fontData);
- nCount = fontData->m_nCount;
- if (bRelease || nCount < 2) {
- delete fontData->m_Obj;
- fontData->m_Obj = NULL;
- }
- }
- }
- {
- pos = m_ImageMap.GetStartPosition();
- while (pos) {
- FX_DWORD objNum;
- CPDF_CountedObject<CPDF_Image*>* imageData;
- m_ImageMap.GetNextAssoc(pos, objNum, imageData);
- nCount = imageData->m_nCount;
- if (bRelease || nCount < 2) {
- delete imageData->m_Obj;
- delete imageData;
- m_ImageMap.RemoveKey(objNum);
- }
- }
- }
- {
- pos = m_ColorSpaceMap.GetStartPosition();
- while (pos) {
- CPDF_Object* csKey;
- CPDF_CountedObject<CPDF_ColorSpace*>* csData;
- m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
- nCount = csData->m_nCount;
- if (bRelease || nCount < 2) {
- csData->m_Obj->ReleaseCS();
- csData->m_Obj = NULL;
- }
- }
- }
- {
- pos = m_IccProfileMap.GetStartPosition();
- while (pos) {
- CPDF_Stream* ipKey;
- CPDF_CountedObject<CPDF_IccProfile*>* ipData;
- m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData);
- nCount = ipData->m_nCount;
- if (bRelease || nCount < 2) {
- FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
- while (pos2) {
- CFX_ByteString bsKey;
- CPDF_Stream* pFindStream = NULL;
- m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream);
- if (ipKey == pFindStream) {
- m_HashProfileMap.RemoveKey(bsKey);
- break;
- }
- }
- delete ipData->m_Obj;
- delete ipData;
- m_IccProfileMap.RemoveKey(ipKey);
- }
- }
- }
- {
- pos = m_FontFileMap.GetStartPosition();
- while (pos) {
- CPDF_Stream* ftKey;
- CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
- m_FontFileMap.GetNextAssoc(pos, ftKey, ftData);
- nCount = ftData->m_nCount;
- if (bRelease || nCount < 2) {
- delete ftData->m_Obj;
- delete ftData;
- m_FontFileMap.RemoveKey(ftKey);
- }
- }
- }
-}
-CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly)
-{
- if (!pFontDict) {
- return NULL;
- }
- if (findOnly) {
- CPDF_CountedObject<CPDF_Font*>* fontData;
- if (m_FontMap.Lookup(pFontDict, fontData)) {
- if (!fontData->m_Obj) {
- return NULL;
- }
- fontData->m_nCount ++;
- return fontData->m_Obj;
- }
- return NULL;
- }
- CPDF_CountedObject<CPDF_Font*>* fontData = NULL;
- if (m_FontMap.Lookup(pFontDict, fontData)) {
- if (fontData->m_Obj) {
- fontData->m_nCount ++;
- return fontData->m_Obj;
- }
- }
- FX_BOOL bNew = FALSE;
- if (!fontData) {
- fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>;
- bNew = TRUE;
- if (!fontData) {
- return NULL;
- }
- }
- CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pFontDict);
- if (!pFont) {
- if (bNew) {
- delete fontData;
- }
- return NULL;
- }
- fontData->m_nCount = 2;
- fontData->m_Obj = pFont;
- m_FontMap.SetAt(pFontDict, fontData);
- return pFont;
-}
-CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding)
-{
- if (fontName.IsEmpty()) {
- return NULL;
- }
- FX_POSITION pos = m_FontMap.GetStartPosition();
- while (pos) {
- CPDF_Dictionary* fontDict;
- CPDF_CountedObject<CPDF_Font*>* fontData;
- m_FontMap.GetNextAssoc(pos, fontDict, fontData);
- CPDF_Font* pFont = fontData->m_Obj;
- if (!pFont) {
- continue;
- }
- if (pFont->GetBaseFont() != fontName) {
- continue;
- }
- if (pFont->IsEmbedded()) {
- continue;
- }
- if (pFont->GetFontType() != PDFFONT_TYPE1) {
- continue;
- }
- if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) {
- continue;
- }
- CPDF_Type1Font* pT1Font = pFont->GetType1Font();
- if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) {
- continue;
- }
- fontData->m_nCount ++;
- return pFont;
- }
- CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
- pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));
- pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));
- pDict->SetAtName(FX_BSTRC("BaseFont"), fontName);
- if (pEncoding) {
- pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize());
- }
- m_pPDFDoc->AddIndirectObject(pDict);
- CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>;
- if (!fontData) {
- return NULL;
- }
- CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict);
- if (!pFont) {
- delete fontData;
- return NULL;
- }
- fontData->m_nCount = 2;
- fontData->m_Obj = pFont;
- m_FontMap.SetAt(pDict, fontData);
- return pFont;
-}
-void CPDF_DocPageData::ReleaseFont(CPDF_Dictionary* pFontDict)
-{
- if (!pFontDict) {
- return;
- }
- CPDF_CountedObject<CPDF_Font*>* fontData;
- if (!m_FontMap.Lookup(pFontDict, fontData)) {
- return;
- }
- if (fontData->m_Obj && --fontData->m_nCount == 0) {
- delete fontData->m_Obj;
- fontData->m_Obj = NULL;
- }
-}
-CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources)
-{
- if (!pCSObj) {
- return NULL;
- }
- if (pCSObj->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = pCSObj->GetConstString();
- CPDF_ColorSpace* pCS = _CSFromName(name);
- if (!pCS && pResources) {
- CPDF_Dictionary* pList = pResources->GetDict(FX_BSTRC("ColorSpace"));
- if (pList) {
- pCSObj = pList->GetElementValue(name);
- return GetColorSpace(pCSObj, NULL);
- }
- }
- if (pCS == NULL || pResources == NULL) {
- return pCS;
- }
- CPDF_Dictionary* pColorSpaces = pResources->GetDict(FX_BSTRC("ColorSpace"));
- if (pColorSpaces == NULL) {
- return pCS;
- }
- CPDF_Object* pDefaultCS = NULL;
- switch (pCS->GetFamily()) {
- case PDFCS_DEVICERGB:
- pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultRGB"));
- break;
- case PDFCS_DEVICEGRAY:
- pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultGray"));
- break;
- case PDFCS_DEVICECMYK:
- pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultCMYK"));
- break;
- }
- if (pDefaultCS == NULL) {
- return pCS;
- }
- return GetColorSpace(pDefaultCS, NULL);
- }
- if (pCSObj->GetType() != PDFOBJ_ARRAY) {
- return NULL;
- }
- CPDF_Array* pArray = (CPDF_Array*)pCSObj;
- if (pArray->GetCount() == 0) {
- return NULL;
- }
- if (pArray->GetCount() == 1) {
- return GetColorSpace(pArray->GetElementValue(0), pResources);
- }
- CPDF_CountedObject<CPDF_ColorSpace*>* csData = NULL;
- if (m_ColorSpaceMap.Lookup(pCSObj, csData)) {
- if (csData->m_Obj) {
- csData->m_nCount++;
- return csData->m_Obj;
- }
- }
- FX_BOOL bNew = FALSE;
- if (!csData) {
- csData = FX_NEW CPDF_CountedObject<CPDF_ColorSpace*>;
- if (!csData) {
- return NULL;
- }
- bNew = TRUE;
- }
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::Load(m_pPDFDoc, pArray);
- if (!pCS) {
- if (bNew) {
- delete csData;
- }
- return NULL;
- }
- csData->m_nCount = 2;
- csData->m_Obj = pCS;
- m_ColorSpaceMap.SetAt(pCSObj, csData);
- return pCS;
-}
-CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj)
-{
- if (!pCSObj) {
- return NULL;
- }
- CPDF_CountedObject<CPDF_ColorSpace*>* csData;
- if (!m_ColorSpaceMap.Lookup(pCSObj, csData)) {
- return NULL;
- }
- if (!csData->m_Obj) {
- return NULL;
- }
- csData->m_nCount ++;
- return csData->m_Obj;
-}
-void CPDF_DocPageData::ReleaseColorSpace(CPDF_Object* pColorSpace)
-{
- if (!pColorSpace) {
- return;
- }
- CPDF_CountedObject<CPDF_ColorSpace*>* csData;
- if (!m_ColorSpaceMap.Lookup(pColorSpace, csData)) {
- return;
- }
- if (csData->m_Obj && --csData->m_nCount == 0) {
- csData->m_Obj->ReleaseCS();
- csData->m_Obj = NULL;
- }
-}
-CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix)
-{
- if (!pPatternObj) {
- return NULL;
- }
- CPDF_CountedObject<CPDF_Pattern*>* ptData = NULL;
- if (m_PatternMap.Lookup(pPatternObj, ptData)) {
- if (ptData->m_Obj) {
- ptData->m_nCount++;
- return ptData->m_Obj;
- }
- }
- FX_BOOL bNew = FALSE;
- if (!ptData) {
- ptData = FX_NEW CPDF_CountedObject<CPDF_Pattern*>;
- bNew = TRUE;
- if (!ptData) {
- return NULL;
- }
- }
- CPDF_Pattern* pPattern = NULL;
- if (bShading) {
- pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, bShading, matrix);
- } else {
- CPDF_Dictionary* pDict = pPatternObj->GetDict();
- if (pDict) {
- int type = pDict->GetInteger(FX_BSTRC("PatternType"));
- if (type == 1) {
- pPattern = FX_NEW CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix);
- } else if (type == 2) {
- pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix);
- }
- }
- }
- if (!pPattern) {
- if (bNew) {
- delete ptData;
- }
- return NULL;
- }
- ptData->m_nCount = 2;
- ptData->m_Obj = pPattern;
- m_PatternMap.SetAt(pPatternObj, ptData);
- return pPattern;
-}
-void CPDF_DocPageData::ReleasePattern(CPDF_Object* pPatternObj)
-{
- if (!pPatternObj) {
- return;
- }
- CPDF_CountedObject<CPDF_Pattern*>* ptData;
- if (!m_PatternMap.Lookup(pPatternObj, ptData)) {
- return;
- }
- if (ptData->m_Obj && --ptData->m_nCount == 0) {
- delete ptData->m_Obj;
- ptData->m_Obj = NULL;
- }
-}
-CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream)
-{
- if (!pImageStream) {
- return NULL;
- }
- FX_DWORD dwImageObjNum = pImageStream->GetObjNum();
- CPDF_CountedObject<CPDF_Image*>* imageData;
- if (m_ImageMap.Lookup(dwImageObjNum, imageData)) {
- imageData->m_nCount ++;
- return imageData->m_Obj;
- }
- imageData = FX_NEW CPDF_CountedObject<CPDF_Image*>;
- if (!imageData) {
- return NULL;
- }
- CPDF_Image* pImage = FX_NEW CPDF_Image(m_pPDFDoc);
- if (!pImage) {
- delete imageData;
- return NULL;
- }
- pImage->LoadImageF((CPDF_Stream*)pImageStream, FALSE);
- imageData->m_nCount = 2;
- imageData->m_Obj = pImage;
- m_ImageMap.SetAt(dwImageObjNum, imageData);
- return pImage;
-}
-void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream)
-{
- if (!pImageStream) {
- return;
- }
- PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL);
-}
-CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents)
-{
- if (!pIccProfileStream) {
- return NULL;
- }
- CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL;
- if (m_IccProfileMap.Lookup(pIccProfileStream, ipData)) {
- ipData->m_nCount++;
- return ipData->m_Obj;
- }
- CPDF_StreamAcc stream;
- stream.LoadAllData(pIccProfileStream, FALSE);
- FX_BYTE digest[20];
- CPDF_Stream* pCopiedStream = NULL;
- CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest);
- if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20), (void*&)pCopiedStream)) {
- m_IccProfileMap.Lookup(pCopiedStream, ipData);
- ipData->m_nCount++;
- return ipData->m_Obj;
- }
- CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents);
- if (!pProfile) {
- return NULL;
- }
- ipData = FX_NEW CPDF_CountedObject<CPDF_IccProfile*>;
- if (!ipData) {
- delete pProfile;
- return NULL;
- }
- ipData->m_nCount = 2;
- ipData->m_Obj = pProfile;
- m_IccProfileMap.SetAt(pIccProfileStream, ipData);
- m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream);
- return pProfile;
-}
-void CPDF_DocPageData::ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile)
-{
- if (!pIccProfileStream && !pIccProfile) {
- return;
- }
- CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL;
- if (m_IccProfileMap.Lookup(pIccProfileStream, ipData) && ipData->m_nCount < 2) {
- FX_POSITION pos = m_HashProfileMap.GetStartPosition();
- while (pos) {
- CFX_ByteString key;
- CPDF_Stream* pFindStream = NULL;
- m_HashProfileMap.GetNextAssoc(pos, key, (void*&)pFindStream);
- if (pIccProfileStream == pFindStream) {
- m_HashProfileMap.RemoveKey(key);
- break;
- }
- }
- }
- PDF_DocPageData_Release<CPDF_Stream*, CPDF_IccProfile*>(m_IccProfileMap, pIccProfileStream, pIccProfile);
-}
-CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(CPDF_Stream* pFontStream)
-{
- if (!pFontStream) {
- return NULL;
- }
- CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
- if (m_FontFileMap.Lookup(pFontStream, ftData)) {
- ftData->m_nCount ++;
- return ftData->m_Obj;
- }
- ftData = FX_NEW CPDF_CountedObject<CPDF_StreamAcc*>;
- if (!ftData) {
- return NULL;
- }
- CPDF_StreamAcc* pFontFile = FX_NEW CPDF_StreamAcc;
- if (!pFontFile) {
- delete ftData;
- return NULL;
- }
- CPDF_Dictionary* pFontDict = pFontStream->GetDict();
- FX_INT32 org_size = pFontDict->GetInteger(FX_BSTRC("Length1")) + pFontDict->GetInteger(FX_BSTRC("Length2")) + pFontDict->GetInteger(FX_BSTRC("Length3"));
- if (org_size < 0) {
- org_size = 0;
- }
- pFontFile->LoadAllData(pFontStream, FALSE, org_size);
- ftData->m_nCount = 2;
- ftData->m_Obj = pFontFile;
- m_FontFileMap.SetAt(pFontStream, ftData);
- return pFontFile;
-}
-void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce)
-{
- if (!pFontStream) {
- return;
- }
- PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce);
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fdrm/fx_crypt.h" +#include "../fpdf_font/font_int.h" +#include "pageint.h" +class CPDF_PageModule : public CPDF_PageModuleDef +{ +public: + CPDF_PageModule() : m_StockGrayCS(PDFCS_DEVICEGRAY), m_StockRGBCS(PDFCS_DEVICERGB), + m_StockCMYKCS(PDFCS_DEVICECMYK) {} + virtual ~CPDF_PageModule() {} + virtual FX_BOOL Installed() + { + return TRUE; + } + virtual CPDF_DocPageData* CreateDocData(CPDF_Document* pDoc) + { + return FX_NEW CPDF_DocPageData(pDoc); + } + virtual void ReleaseDoc(CPDF_Document* pDoc); + virtual void ClearDoc(CPDF_Document* pDoc); + virtual CPDF_FontGlobals* GetFontGlobals() + { + return &m_FontGlobals; + } + virtual void ClearStockFont(CPDF_Document* pDoc) + { + m_FontGlobals.Clear(pDoc); + } + virtual CPDF_ColorSpace* GetStockCS(int family); + virtual void NotifyCJKAvailable(); + CPDF_FontGlobals m_FontGlobals; + CPDF_DeviceCS m_StockGrayCS; + CPDF_DeviceCS m_StockRGBCS; + CPDF_DeviceCS m_StockCMYKCS; + CPDF_PatternCS m_StockPatternCS; +}; +CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family) +{ + if (family == PDFCS_DEVICEGRAY) { + return &m_StockGrayCS; + } + if (family == PDFCS_DEVICERGB) { + return &m_StockRGBCS; + } + if (family == PDFCS_DEVICECMYK) { + return &m_StockCMYKCS; + } + if (family == PDFCS_PATTERN) { + return &m_StockPatternCS; + } + return NULL; +} +void CPDF_ModuleMgr::InitPageModule() +{ + if (m_pPageModule) { + delete m_pPageModule; + } + CPDF_PageModule* pPageModule = FX_NEW CPDF_PageModule; + m_pPageModule = pPageModule; +} +void CPDF_PageModule::ReleaseDoc(CPDF_Document* pDoc) +{ + delete pDoc->GetPageData(); +} +void CPDF_PageModule::ClearDoc(CPDF_Document* pDoc) +{ + pDoc->GetPageData()->Clear(FALSE); +} +void CPDF_PageModule::NotifyCJKAvailable() +{ + m_FontGlobals.m_CMapManager.ReloadAll(); +} +CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) +{ + if (!pFontDict) { + return NULL; + } + return GetValidatePageData()->GetFont(pFontDict, FALSE); +} +CPDF_Font* CPDF_Document::FindFont(CPDF_Dictionary* pFontDict) +{ + if (!pFontDict) { + return NULL; + } + return GetValidatePageData()->GetFont(pFontDict, TRUE); +} +CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) +{ + if (pStream == NULL) { + return NULL; + } + return GetValidatePageData()->GetFontFileStreamAcc(pStream); +} +CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name); +CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) +{ + return GetValidatePageData()->GetColorSpace(pCSObj, pResources); +} +CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) +{ + return GetValidatePageData()->GetPattern(pPatternObj, bShading, matrix); +} +CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream, int nComponents) +{ + return GetValidatePageData()->GetIccProfile(pStream, nComponents); +} +CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) +{ + if (!pObj) { + return NULL; + } + FXSYS_assert(pObj->GetObjNum()); + return GetValidatePageData()->GetImage(pObj); +} +void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj) +{ + if (!pCSObj) { + return; + } + GetPageData()->ReleaseColorSpace(pCSObj); +} +CPDF_DocPageData::CPDF_DocPageData(CPDF_Document *pPDFDoc) + : m_pPDFDoc(pPDFDoc) + , m_FontMap() + , m_ColorSpaceMap() + , m_PatternMap() + , m_ImageMap() + , m_IccProfileMap() + , m_FontFileMap() +{ + m_FontMap.InitHashTable(64); + m_ColorSpaceMap.InitHashTable(32); + m_PatternMap.InitHashTable(16); + m_ImageMap.InitHashTable(64); + m_IccProfileMap.InitHashTable(16); + m_FontFileMap.InitHashTable(32); +} +CPDF_DocPageData::~CPDF_DocPageData() +{ + Clear(FALSE); + Clear(TRUE); + FX_POSITION pos = NULL; +} +void CPDF_DocPageData::Clear(FX_BOOL bRelease) +{ + FX_POSITION pos; + FX_DWORD nCount; + { + pos = m_PatternMap.GetStartPosition(); + while (pos) { + CPDF_Object* ptObj; + CPDF_CountedObject<CPDF_Pattern*>* ptData; + m_PatternMap.GetNextAssoc(pos, ptObj, ptData); + nCount = ptData->m_nCount; + if (bRelease || nCount < 2) { + delete ptData->m_Obj; + ptData->m_Obj = NULL; + } + } + } + { + pos = m_FontMap.GetStartPosition(); + while (pos) { + CPDF_Dictionary* fontDict; + CPDF_CountedObject<CPDF_Font*>* fontData; + m_FontMap.GetNextAssoc(pos, fontDict, fontData); + nCount = fontData->m_nCount; + if (bRelease || nCount < 2) { + delete fontData->m_Obj; + fontData->m_Obj = NULL; + } + } + } + { + pos = m_ImageMap.GetStartPosition(); + while (pos) { + FX_DWORD objNum; + CPDF_CountedObject<CPDF_Image*>* imageData; + m_ImageMap.GetNextAssoc(pos, objNum, imageData); + nCount = imageData->m_nCount; + if (bRelease || nCount < 2) { + delete imageData->m_Obj; + delete imageData; + m_ImageMap.RemoveKey(objNum); + } + } + } + { + pos = m_ColorSpaceMap.GetStartPosition(); + while (pos) { + CPDF_Object* csKey; + CPDF_CountedObject<CPDF_ColorSpace*>* csData; + m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData); + nCount = csData->m_nCount; + if (bRelease || nCount < 2) { + csData->m_Obj->ReleaseCS(); + csData->m_Obj = NULL; + } + } + } + { + pos = m_IccProfileMap.GetStartPosition(); + while (pos) { + CPDF_Stream* ipKey; + CPDF_CountedObject<CPDF_IccProfile*>* ipData; + m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData); + nCount = ipData->m_nCount; + if (bRelease || nCount < 2) { + FX_POSITION pos2 = m_HashProfileMap.GetStartPosition(); + while (pos2) { + CFX_ByteString bsKey; + CPDF_Stream* pFindStream = NULL; + m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream); + if (ipKey == pFindStream) { + m_HashProfileMap.RemoveKey(bsKey); + break; + } + } + delete ipData->m_Obj; + delete ipData; + m_IccProfileMap.RemoveKey(ipKey); + } + } + } + { + pos = m_FontFileMap.GetStartPosition(); + while (pos) { + CPDF_Stream* ftKey; + CPDF_CountedObject<CPDF_StreamAcc*>* ftData; + m_FontFileMap.GetNextAssoc(pos, ftKey, ftData); + nCount = ftData->m_nCount; + if (bRelease || nCount < 2) { + delete ftData->m_Obj; + delete ftData; + m_FontFileMap.RemoveKey(ftKey); + } + } + } +} +CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly) +{ + if (!pFontDict) { + return NULL; + } + if (findOnly) { + CPDF_CountedObject<CPDF_Font*>* fontData; + if (m_FontMap.Lookup(pFontDict, fontData)) { + if (!fontData->m_Obj) { + return NULL; + } + fontData->m_nCount ++; + return fontData->m_Obj; + } + return NULL; + } + CPDF_CountedObject<CPDF_Font*>* fontData = NULL; + if (m_FontMap.Lookup(pFontDict, fontData)) { + if (fontData->m_Obj) { + fontData->m_nCount ++; + return fontData->m_Obj; + } + } + FX_BOOL bNew = FALSE; + if (!fontData) { + fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; + bNew = TRUE; + if (!fontData) { + return NULL; + } + } + CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pFontDict); + if (!pFont) { + if (bNew) { + delete fontData; + } + return NULL; + } + fontData->m_nCount = 2; + fontData->m_Obj = pFont; + m_FontMap.SetAt(pFontDict, fontData); + return pFont; +} +CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding) +{ + if (fontName.IsEmpty()) { + return NULL; + } + FX_POSITION pos = m_FontMap.GetStartPosition(); + while (pos) { + CPDF_Dictionary* fontDict; + CPDF_CountedObject<CPDF_Font*>* fontData; + m_FontMap.GetNextAssoc(pos, fontDict, fontData); + CPDF_Font* pFont = fontData->m_Obj; + if (!pFont) { + continue; + } + if (pFont->GetBaseFont() != fontName) { + continue; + } + if (pFont->IsEmbedded()) { + continue; + } + if (pFont->GetFontType() != PDFFONT_TYPE1) { + continue; + } + if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) { + continue; + } + CPDF_Type1Font* pT1Font = pFont->GetType1Font(); + if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) { + continue; + } + fontData->m_nCount ++; + return pFont; + } + CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; + pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); + pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); + pDict->SetAtName(FX_BSTRC("BaseFont"), fontName); + if (pEncoding) { + pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize()); + } + m_pPDFDoc->AddIndirectObject(pDict); + CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; + if (!fontData) { + return NULL; + } + CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict); + if (!pFont) { + delete fontData; + return NULL; + } + fontData->m_nCount = 2; + fontData->m_Obj = pFont; + m_FontMap.SetAt(pDict, fontData); + return pFont; +} +void CPDF_DocPageData::ReleaseFont(CPDF_Dictionary* pFontDict) +{ + if (!pFontDict) { + return; + } + CPDF_CountedObject<CPDF_Font*>* fontData; + if (!m_FontMap.Lookup(pFontDict, fontData)) { + return; + } + if (fontData->m_Obj && --fontData->m_nCount == 0) { + delete fontData->m_Obj; + fontData->m_Obj = NULL; + } +} +CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources) +{ + if (!pCSObj) { + return NULL; + } + if (pCSObj->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = pCSObj->GetConstString(); + CPDF_ColorSpace* pCS = _CSFromName(name); + if (!pCS && pResources) { + CPDF_Dictionary* pList = pResources->GetDict(FX_BSTRC("ColorSpace")); + if (pList) { + pCSObj = pList->GetElementValue(name); + return GetColorSpace(pCSObj, NULL); + } + } + if (pCS == NULL || pResources == NULL) { + return pCS; + } + CPDF_Dictionary* pColorSpaces = pResources->GetDict(FX_BSTRC("ColorSpace")); + if (pColorSpaces == NULL) { + return pCS; + } + CPDF_Object* pDefaultCS = NULL; + switch (pCS->GetFamily()) { + case PDFCS_DEVICERGB: + pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultRGB")); + break; + case PDFCS_DEVICEGRAY: + pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultGray")); + break; + case PDFCS_DEVICECMYK: + pDefaultCS = pColorSpaces->GetElementValue(FX_BSTRC("DefaultCMYK")); + break; + } + if (pDefaultCS == NULL) { + return pCS; + } + return GetColorSpace(pDefaultCS, NULL); + } + if (pCSObj->GetType() != PDFOBJ_ARRAY) { + return NULL; + } + CPDF_Array* pArray = (CPDF_Array*)pCSObj; + if (pArray->GetCount() == 0) { + return NULL; + } + if (pArray->GetCount() == 1) { + return GetColorSpace(pArray->GetElementValue(0), pResources); + } + CPDF_CountedObject<CPDF_ColorSpace*>* csData = NULL; + if (m_ColorSpaceMap.Lookup(pCSObj, csData)) { + if (csData->m_Obj) { + csData->m_nCount++; + return csData->m_Obj; + } + } + FX_BOOL bNew = FALSE; + if (!csData) { + csData = FX_NEW CPDF_CountedObject<CPDF_ColorSpace*>; + if (!csData) { + return NULL; + } + bNew = TRUE; + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::Load(m_pPDFDoc, pArray); + if (!pCS) { + if (bNew) { + delete csData; + } + return NULL; + } + csData->m_nCount = 2; + csData->m_Obj = pCS; + m_ColorSpaceMap.SetAt(pCSObj, csData); + return pCS; +} +CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) +{ + if (!pCSObj) { + return NULL; + } + CPDF_CountedObject<CPDF_ColorSpace*>* csData; + if (!m_ColorSpaceMap.Lookup(pCSObj, csData)) { + return NULL; + } + if (!csData->m_Obj) { + return NULL; + } + csData->m_nCount ++; + return csData->m_Obj; +} +void CPDF_DocPageData::ReleaseColorSpace(CPDF_Object* pColorSpace) +{ + if (!pColorSpace) { + return; + } + CPDF_CountedObject<CPDF_ColorSpace*>* csData; + if (!m_ColorSpaceMap.Lookup(pColorSpace, csData)) { + return; + } + if (csData->m_Obj && --csData->m_nCount == 0) { + csData->m_Obj->ReleaseCS(); + csData->m_Obj = NULL; + } +} +CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix) +{ + if (!pPatternObj) { + return NULL; + } + CPDF_CountedObject<CPDF_Pattern*>* ptData = NULL; + if (m_PatternMap.Lookup(pPatternObj, ptData)) { + if (ptData->m_Obj) { + ptData->m_nCount++; + return ptData->m_Obj; + } + } + FX_BOOL bNew = FALSE; + if (!ptData) { + ptData = FX_NEW CPDF_CountedObject<CPDF_Pattern*>; + bNew = TRUE; + if (!ptData) { + return NULL; + } + } + CPDF_Pattern* pPattern = NULL; + if (bShading) { + pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, bShading, matrix); + } else { + CPDF_Dictionary* pDict = pPatternObj->GetDict(); + if (pDict) { + int type = pDict->GetInteger(FX_BSTRC("PatternType")); + if (type == 1) { + pPattern = FX_NEW CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); + } else if (type == 2) { + pPattern = FX_NEW CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); + } + } + } + if (!pPattern) { + if (bNew) { + delete ptData; + } + return NULL; + } + ptData->m_nCount = 2; + ptData->m_Obj = pPattern; + m_PatternMap.SetAt(pPatternObj, ptData); + return pPattern; +} +void CPDF_DocPageData::ReleasePattern(CPDF_Object* pPatternObj) +{ + if (!pPatternObj) { + return; + } + CPDF_CountedObject<CPDF_Pattern*>* ptData; + if (!m_PatternMap.Lookup(pPatternObj, ptData)) { + return; + } + if (ptData->m_Obj && --ptData->m_nCount == 0) { + delete ptData->m_Obj; + ptData->m_Obj = NULL; + } +} +CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) +{ + if (!pImageStream) { + return NULL; + } + FX_DWORD dwImageObjNum = pImageStream->GetObjNum(); + CPDF_CountedObject<CPDF_Image*>* imageData; + if (m_ImageMap.Lookup(dwImageObjNum, imageData)) { + imageData->m_nCount ++; + return imageData->m_Obj; + } + imageData = FX_NEW CPDF_CountedObject<CPDF_Image*>; + if (!imageData) { + return NULL; + } + CPDF_Image* pImage = FX_NEW CPDF_Image(m_pPDFDoc); + if (!pImage) { + delete imageData; + return NULL; + } + pImage->LoadImageF((CPDF_Stream*)pImageStream, FALSE); + imageData->m_nCount = 2; + imageData->m_Obj = pImage; + m_ImageMap.SetAt(dwImageObjNum, imageData); + return pImage; +} +void CPDF_DocPageData::ReleaseImage(CPDF_Object* pImageStream) +{ + if (!pImageStream) { + return; + } + PDF_DocPageData_Release<FX_DWORD, CPDF_Image*>(m_ImageMap, pImageStream->GetObjNum(), NULL); +} +CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents) +{ + if (!pIccProfileStream) { + return NULL; + } + CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; + if (m_IccProfileMap.Lookup(pIccProfileStream, ipData)) { + ipData->m_nCount++; + return ipData->m_Obj; + } + CPDF_StreamAcc stream; + stream.LoadAllData(pIccProfileStream, FALSE); + FX_BYTE digest[20]; + CPDF_Stream* pCopiedStream = NULL; + CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); + if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20), (void*&)pCopiedStream)) { + m_IccProfileMap.Lookup(pCopiedStream, ipData); + ipData->m_nCount++; + return ipData->m_Obj; + } + CPDF_IccProfile* pProfile = FX_NEW CPDF_IccProfile(stream.GetData(), stream.GetSize(), nComponents); + if (!pProfile) { + return NULL; + } + ipData = FX_NEW CPDF_CountedObject<CPDF_IccProfile*>; + if (!ipData) { + delete pProfile; + return NULL; + } + ipData->m_nCount = 2; + ipData->m_Obj = pProfile; + m_IccProfileMap.SetAt(pIccProfileStream, ipData); + m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream); + return pProfile; +} +void CPDF_DocPageData::ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile) +{ + if (!pIccProfileStream && !pIccProfile) { + return; + } + CPDF_CountedObject<CPDF_IccProfile*>* ipData = NULL; + if (m_IccProfileMap.Lookup(pIccProfileStream, ipData) && ipData->m_nCount < 2) { + FX_POSITION pos = m_HashProfileMap.GetStartPosition(); + while (pos) { + CFX_ByteString key; + CPDF_Stream* pFindStream = NULL; + m_HashProfileMap.GetNextAssoc(pos, key, (void*&)pFindStream); + if (pIccProfileStream == pFindStream) { + m_HashProfileMap.RemoveKey(key); + break; + } + } + } + PDF_DocPageData_Release<CPDF_Stream*, CPDF_IccProfile*>(m_IccProfileMap, pIccProfileStream, pIccProfile); +} +CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(CPDF_Stream* pFontStream) +{ + if (!pFontStream) { + return NULL; + } + CPDF_CountedObject<CPDF_StreamAcc*>* ftData; + if (m_FontFileMap.Lookup(pFontStream, ftData)) { + ftData->m_nCount ++; + return ftData->m_Obj; + } + ftData = FX_NEW CPDF_CountedObject<CPDF_StreamAcc*>; + if (!ftData) { + return NULL; + } + CPDF_StreamAcc* pFontFile = FX_NEW CPDF_StreamAcc; + if (!pFontFile) { + delete ftData; + return NULL; + } + CPDF_Dictionary* pFontDict = pFontStream->GetDict(); + FX_INT32 org_size = pFontDict->GetInteger(FX_BSTRC("Length1")) + pFontDict->GetInteger(FX_BSTRC("Length2")) + pFontDict->GetInteger(FX_BSTRC("Length3")); + if (org_size < 0) { + org_size = 0; + } + pFontFile->LoadAllData(pFontStream, FALSE, org_size); + ftData->m_nCount = 2; + ftData->m_Obj = pFontFile; + m_FontFileMap.SetAt(pFontStream, ftData); + return pFontFile; +} +void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce) +{ + if (!pFontStream) { + return; + } + PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce); +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp index 335460f320..5b178f955e 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp @@ -1,886 +1,886 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "pageint.h"
-#include <limits.h>
-class CPDF_PSEngine;
-typedef enum {PSOP_ADD, PSOP_SUB, PSOP_MUL, PSOP_DIV, PSOP_IDIV, PSOP_MOD,
- PSOP_NEG, PSOP_ABS, PSOP_CEILING, PSOP_FLOOR, PSOP_ROUND, PSOP_TRUNCATE,
- PSOP_SQRT, PSOP_SIN, PSOP_COS, PSOP_ATAN, PSOP_EXP, PSOP_LN, PSOP_LOG,
- PSOP_CVI, PSOP_CVR, PSOP_EQ, PSOP_NE, PSOP_GT, PSOP_GE, PSOP_LT, PSOP_LE,
- PSOP_AND, PSOP_OR, PSOP_XOR, PSOP_NOT, PSOP_BITSHIFT, PSOP_TRUE, PSOP_FALSE,
- PSOP_IF, PSOP_IFELSE, PSOP_POP, PSOP_EXCH, PSOP_DUP, PSOP_COPY,
- PSOP_INDEX, PSOP_ROLL, PSOP_PROC, PSOP_CONST
- } PDF_PSOP;
-class CPDF_PSProc : public CFX_Object
-{
-public:
- ~CPDF_PSProc();
- FX_BOOL Parse(CPDF_SimpleParser& parser);
- FX_BOOL Execute(CPDF_PSEngine* pEngine);
- CFX_PtrArray m_Operators;
-};
-#define PSENGINE_STACKSIZE 100
-class CPDF_PSEngine : public CFX_Object
-{
-public:
- CPDF_PSEngine();
- ~CPDF_PSEngine();
- FX_BOOL Parse(const FX_CHAR* string, int size);
- FX_BOOL Execute()
- {
- return m_MainProc.Execute(this);
- }
- FX_BOOL DoOperator(PDF_PSOP op);
- void Reset()
- {
- m_StackCount = 0;
- }
- void Push(FX_FLOAT value);
- void Push(int value)
- {
- Push((FX_FLOAT)value);
- }
- FX_FLOAT Pop();
- int GetStackSize()
- {
- return m_StackCount;
- }
-private:
- FX_FLOAT m_Stack[PSENGINE_STACKSIZE];
- int m_StackCount;
- CPDF_PSProc m_MainProc;
-};
-CPDF_PSProc::~CPDF_PSProc()
-{
- int size = m_Operators.GetSize();
- for (int i = 0; i < size; i ++) {
- if (m_Operators[i] == (FX_LPVOID)PSOP_PROC) {
- delete (CPDF_PSProc*)m_Operators[i + 1];
- i ++;
- } else if (m_Operators[i] == (FX_LPVOID)PSOP_CONST) {
- FX_Free((FX_FLOAT*)m_Operators[i + 1]);
- i ++;
- }
- }
-}
-#pragma optimize( "", off )
-FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine)
-{
- int size = m_Operators.GetSize();
- for (int i = 0; i < size; i ++) {
- PDF_PSOP op = (PDF_PSOP)(FX_UINTPTR)m_Operators[i];
- if (op == PSOP_PROC) {
- i ++;
- } else if (op == PSOP_CONST) {
- pEngine->Push(*(FX_FLOAT*)m_Operators[i + 1]);
- i ++;
- } else if (op == PSOP_IF) {
- if (i < 2 || m_Operators[i - 2] != (FX_LPVOID)PSOP_PROC) {
- return FALSE;
- }
- if ((int)pEngine->Pop()) {
- ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine);
- }
- } else if (op == PSOP_IFELSE) {
- if (i < 4 || m_Operators[i - 2] != (FX_LPVOID)PSOP_PROC ||
- m_Operators[i - 4] != (FX_LPVOID)PSOP_PROC) {
- return FALSE;
- }
- if ((int)pEngine->Pop()) {
- ((CPDF_PSProc*)m_Operators[i - 3])->Execute(pEngine);
- } else {
- ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine);
- }
- } else {
- pEngine->DoOperator(op);
- }
- }
- return TRUE;
-}
-#pragma optimize( "", on )
-CPDF_PSEngine::CPDF_PSEngine()
-{
- m_StackCount = 0;
-}
-CPDF_PSEngine::~CPDF_PSEngine()
-{
-}
-void CPDF_PSEngine::Push(FX_FLOAT v)
-{
- if (m_StackCount == 100) {
- return;
- }
- m_Stack[m_StackCount++] = v;
-}
-FX_FLOAT CPDF_PSEngine::Pop()
-{
- if (m_StackCount == 0) {
- return 0;
- }
- return m_Stack[--m_StackCount];
-}
-const struct _PDF_PSOpName {
- const FX_CHAR* name;
- PDF_PSOP op;
-} _PDF_PSOpNames[] = {
- {"add", PSOP_ADD}, {"sub", PSOP_SUB}, {"mul", PSOP_MUL}, {"div", PSOP_DIV},
- {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD}, {"neg", PSOP_NEG}, {"abs", PSOP_ABS},
- {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR}, {"round", PSOP_ROUND},
- {"truncate", PSOP_TRUNCATE}, {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN},
- {"cos", PSOP_COS}, {"atan", PSOP_ATAN}, {"exp", PSOP_EXP}, {"ln", PSOP_LN},
- {"log", PSOP_LOG}, {"cvi", PSOP_CVI}, {"cvr", PSOP_CVR}, {"eq", PSOP_EQ},
- {"ne", PSOP_NE}, {"gt", PSOP_GT}, {"ge", PSOP_GE}, {"lt", PSOP_LT},
- {"le", PSOP_LE}, {"and", PSOP_AND}, {"or", PSOP_OR}, {"xor", PSOP_XOR},
- {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT}, {"true", PSOP_TRUE},
- {"false", PSOP_FALSE}, {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE},
- {"pop", PSOP_POP}, {"exch", PSOP_EXCH}, {"dup", PSOP_DUP},
- {"copy", PSOP_COPY}, {"index", PSOP_INDEX}, {"roll", PSOP_ROLL},
- {NULL, PSOP_PROC}
-};
-FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* string, int size)
-{
- CPDF_SimpleParser parser((FX_LPBYTE)string, size);
- CFX_ByteStringC word = parser.GetWord();
- if (word != FX_BSTRC("{")) {
- return FALSE;
- }
- return m_MainProc.Parse(parser);
-}
-FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser& parser)
-{
- while (1) {
- CFX_ByteStringC word = parser.GetWord();
- if (word.IsEmpty()) {
- return FALSE;
- }
- if (word == FX_BSTRC("}")) {
- return TRUE;
- }
- if (word == FX_BSTRC("{")) {
- CPDF_PSProc* pProc = FX_NEW CPDF_PSProc;
- m_Operators.Add((FX_LPVOID)PSOP_PROC);
- m_Operators.Add(pProc);
- if (!pProc->Parse(parser)) {
- return FALSE;
- }
- } else {
- int i = 0;
- while (_PDF_PSOpNames[i].name) {
- if (word == CFX_ByteStringC(_PDF_PSOpNames[i].name)) {
- m_Operators.Add((FX_LPVOID)_PDF_PSOpNames[i].op);
- break;
- }
- i ++;
- }
- if (_PDF_PSOpNames[i].name == NULL) {
- FX_FLOAT* pd = FX_Alloc(FX_FLOAT, 1);
- *pd = FX_atof(word);
- m_Operators.Add((FX_LPVOID)PSOP_CONST);
- m_Operators.Add(pd);
- }
- }
- }
-}
-#define PI 3.1415926535897932384626433832795f
-FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op)
-{
- int i1, i2;
- FX_FLOAT d1, d2;
- switch (op) {
- case PSOP_ADD:
- d1 = Pop();
- d2 = Pop();
- Push(d1 + d2);
- break;
- case PSOP_SUB:
- d2 = Pop();
- d1 = Pop();
- Push(d1 - d2);
- break;
- case PSOP_MUL:
- d1 = Pop();
- d2 = Pop();
- Push(d1 * d2);
- break;
- case PSOP_DIV:
- d2 = Pop();
- d1 = Pop();
- Push(d1 / d2);
- break;
- case PSOP_IDIV:
- i2 = (int)Pop();
- i1 = (int)Pop();
- Push(i1 / i2);
- break;
- case PSOP_MOD:
- i2 = (int)Pop();
- i1 = (int)Pop();
- Push(i1 % i2);
- break;
- case PSOP_NEG:
- d1 = Pop();
- Push(-d1);
- break;
- case PSOP_ABS:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_fabs(d1));
- break;
- case PSOP_CEILING:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_ceil(d1));
- break;
- case PSOP_FLOOR:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_floor(d1));
- break;
- case PSOP_ROUND:
- d1 = Pop();
- Push(FXSYS_round(d1));
- break;
- case PSOP_TRUNCATE:
- i1 = (int)Pop();
- Push(i1);
- break;
- case PSOP_SQRT:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_sqrt(d1));
- break;
- case PSOP_SIN:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_sin(d1 * PI / 180.0f));
- break;
- case PSOP_COS:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_cos(d1 * PI / 180.0f));
- break;
- case PSOP_ATAN:
- d2 = Pop();
- d1 = Pop();
- d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / PI);
- if (d1 < 0) {
- d1 += 360;
- }
- Push(d1);
- break;
- case PSOP_EXP:
- d2 = Pop();
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_pow(d1, d2));
- break;
- case PSOP_LN:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_log(d1));
- break;
- case PSOP_LOG:
- d1 = Pop();
- Push((FX_FLOAT)FXSYS_log10(d1));
- break;
- case PSOP_CVI:
- i1 = (int)Pop();
- Push(i1);
- break;
- case PSOP_CVR:
- break;
- case PSOP_EQ:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 == d2));
- break;
- case PSOP_NE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 != d2));
- break;
- case PSOP_GT:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 > d2));
- break;
- case PSOP_GE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 >= d2));
- break;
- case PSOP_LT:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 < d2));
- break;
- case PSOP_LE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 <= d2));
- break;
- case PSOP_AND:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 & i2);
- break;
- case PSOP_OR:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 | i2);
- break;
- case PSOP_XOR:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 ^ i2);
- break;
- case PSOP_NOT:
- i1 = (int)Pop();
- Push((int)!i1);
- break;
- case PSOP_BITSHIFT: {
- int shift = (int)Pop();
- int i = (int)Pop();
- if (shift > 0) {
- Push(i << shift);
- } else {
- Push(i >> -shift);
- }
- break;
- }
- case PSOP_TRUE:
- Push(1);
- break;
- case PSOP_FALSE:
- Push(0);
- break;
- case PSOP_POP:
- Pop();
- break;
- case PSOP_EXCH:
- d2 = Pop();
- d1 = Pop();
- Push(d2);
- Push(d1);
- break;
- case PSOP_DUP:
- d1 = Pop();
- Push(d1);
- Push(d1);
- break;
- case PSOP_COPY: {
- int n = (int)Pop();
- if (n < 0 || n > PSENGINE_STACKSIZE || m_StackCount + n > PSENGINE_STACKSIZE || n > m_StackCount) {
- break;
- }
- for (int i = 0; i < n; i ++) {
- m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
- }
- m_StackCount += n;
- break;
- }
- case PSOP_INDEX: {
- int n = (int)Pop();
- if (n < 0 || n >= m_StackCount) {
- break;
- }
- Push(m_Stack[m_StackCount - n - 1]);
- break;
- }
- case PSOP_ROLL: {
- int j = (int)Pop();
- int n = (int)Pop();
- if (m_StackCount == 0) {
- break;
- }
- if (n < 0 || n > m_StackCount) {
- break;
- }
- if (j < 0)
- for (int i = 0; i < -j; i ++) {
- FX_FLOAT first = m_Stack[m_StackCount - n];
- for (int ii = 0; ii < n - 1; ii ++) {
- m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1];
- }
- m_Stack[m_StackCount - 1] = first;
- }
- else
- for (int i = 0; i < j; i ++) {
- FX_FLOAT last = m_Stack[m_StackCount - 1];
- int ii;
- for (ii = 0; ii < n - 1; ii ++) {
- m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2];
- }
- m_Stack[m_StackCount - ii - 1] = last;
- }
- break;
- }
- default:
- break;
- }
- return TRUE;
-}
-static FX_FLOAT PDF_Interpolate(FX_FLOAT x, FX_FLOAT xmin, FX_FLOAT xmax, FX_FLOAT ymin, FX_FLOAT ymax)
-{
- return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin;
-}
-static FX_DWORD _GetBits32(FX_LPCBYTE pData, int bitpos, int nbits)
-{
- int result = 0;
- for (int i = 0; i < nbits; i ++)
- if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) {
- result |= 1 << (nbits - i - 1);
- }
- return result;
-}
-typedef struct {
- FX_FLOAT encode_max, encode_min;
- int sizes;
-} SampleEncodeInfo;
-typedef struct {
- FX_FLOAT decode_max, decode_min;
-} SampleDecodeInfo;
-class CPDF_SampledFunc : public CPDF_Function
-{
-public:
- CPDF_SampledFunc();
- virtual ~CPDF_SampledFunc();
- virtual FX_BOOL v_Init(CPDF_Object* pObj);
- virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
- SampleEncodeInfo* m_pEncodeInfo;
- SampleDecodeInfo* m_pDecodeInfo;
- FX_DWORD m_nBitsPerSample, m_SampleMax;
- CPDF_StreamAcc* m_pSampleStream;
-};
-CPDF_SampledFunc::CPDF_SampledFunc()
-{
- m_pSampleStream = NULL;
- m_pEncodeInfo = NULL;
- m_pDecodeInfo = NULL;
-}
-CPDF_SampledFunc::~CPDF_SampledFunc()
-{
- if (m_pSampleStream) {
- delete m_pSampleStream;
- }
- if (m_pEncodeInfo) {
- FX_Free(m_pEncodeInfo);
- }
- if (m_pDecodeInfo) {
- FX_Free(m_pDecodeInfo);
- }
-}
-FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj)
-{
- if (pObj->GetType() != PDFOBJ_STREAM) {
- return FALSE;
- }
- CPDF_Stream* pStream = (CPDF_Stream*)pObj;
- CPDF_Dictionary* pDict = pStream->GetDict();
- CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size"));
- CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode"));
- CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode"));
- m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample"));
- m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
- m_pSampleStream = FX_NEW CPDF_StreamAcc;
- m_pSampleStream->LoadAllData(pStream, FALSE);
- m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs);
- int i;
- FX_DWORD nTotalSamples = 1;
- for (i = 0; i < m_nInputs; i ++) {
- m_pEncodeInfo[i].sizes = pSize->GetInteger(i);
- if (!pSize && i == 0) {
- m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size"));
- }
- if (nTotalSamples > 0 && (FX_UINT32)(m_pEncodeInfo[i].sizes) > UINT_MAX / nTotalSamples) {
- return FALSE;
- }
- nTotalSamples *= m_pEncodeInfo[i].sizes;
- if (pEncode) {
- m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2);
- m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1);
- } else {
- m_pEncodeInfo[i].encode_min = 0;
- if (m_pEncodeInfo[i].sizes == 1) {
- m_pEncodeInfo[i].encode_max = 1;
- } else {
- m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
- }
- }
- }
- if (nTotalSamples > 0 && m_nBitsPerSample > UINT_MAX / nTotalSamples) {
- return FALSE;
- }
- nTotalSamples *= m_nBitsPerSample;
- if (nTotalSamples > 0 && ((FX_UINT32)m_nOutputs) > UINT_MAX / nTotalSamples) {
- return FALSE;
- }
- nTotalSamples *= m_nOutputs;
- if (nTotalSamples == 0 || m_pSampleStream->GetSize() * 8 < nTotalSamples) {
- return FALSE;
- }
- m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs);
- for (i = 0; i < m_nOutputs; i ++) {
- if (pDecode) {
- m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i);
- m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1);
- } else {
- m_pDecodeInfo[i].decode_min = m_pRanges[i * 2];
- m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const
-{
- int pos = 0;
- CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs);
- FX_FLOAT* encoded_input = encoded_input_buf;
- CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2);
- int* index = int_buf;
- int* blocksize = index + m_nInputs;
- for (int i = 0; i < m_nInputs; i ++) {
- if (i == 0) {
- blocksize[i] = 1;
- } else {
- blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes;
- }
- encoded_input[i] = PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
- m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max);
- index[i] = (int)encoded_input[i];
- if (index[i] < 0) {
- index[i] = 0;
- } else if (index[i] > m_pEncodeInfo[i].sizes - 1) {
- index[i] = m_pEncodeInfo[i].sizes - 1;
- }
- pos += index[i] * blocksize[i];
- }
- int bitpos = pos * m_nBitsPerSample * m_nOutputs;
- FX_LPCBYTE pSampleData = m_pSampleStream->GetData();
- if (pSampleData == NULL) {
- return FALSE;
- }
- for (int j = 0; j < m_nOutputs; j ++) {
- FX_DWORD sample = _GetBits32(pSampleData, bitpos + j * m_nBitsPerSample, m_nBitsPerSample);
- FX_FLOAT encoded = (FX_FLOAT)sample;
- for (int i = 0; i < m_nInputs; i ++) {
- if (index[i] == m_pEncodeInfo[i].sizes - 1) {
- if (index[i] == 0) {
- encoded = encoded_input[i] * (FX_FLOAT)sample;
- }
- } else {
- int bitpos1 = bitpos + m_nBitsPerSample * m_nOutputs * blocksize[i];
- FX_DWORD sample1 = _GetBits32(pSampleData, bitpos1 + j * m_nBitsPerSample, m_nBitsPerSample);
- encoded += (encoded_input[i] - index[i]) * ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
- }
- }
- results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
- m_pDecodeInfo[j].decode_min, m_pDecodeInfo[j].decode_max);
- }
- return TRUE;
-}
-class CPDF_PSFunc : public CPDF_Function
-{
-public:
- virtual FX_BOOL v_Init(CPDF_Object* pObj);
- virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
- CPDF_PSEngine m_PS;
-};
-FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj)
-{
- CPDF_Stream* pStream = (CPDF_Stream*)pObj;
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream, FALSE);
- return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize());
-}
-FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const
-{
- CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS;
- PS.Reset();
- int i;
- for (i = 0; i < m_nInputs; i ++) {
- PS.Push(inputs[i]);
- }
- PS.Execute();
- if (PS.GetStackSize() < m_nOutputs) {
- return FALSE;
- }
- for (i = 0; i < m_nOutputs; i ++) {
- results[m_nOutputs - i - 1] = PS.Pop();
- }
- return TRUE;
-}
-class CPDF_ExpIntFunc : public CPDF_Function
-{
-public:
- CPDF_ExpIntFunc();
- virtual ~CPDF_ExpIntFunc();
- virtual FX_BOOL v_Init(CPDF_Object* pObj);
- virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
- FX_FLOAT m_Exponent;
- FX_FLOAT* m_pBeginValues;
- FX_FLOAT* m_pEndValues;
- int m_nOrigOutputs;
-};
-CPDF_ExpIntFunc::CPDF_ExpIntFunc()
-{
- m_pBeginValues = NULL;
- m_pEndValues = NULL;
-}
-CPDF_ExpIntFunc::~CPDF_ExpIntFunc()
-{
- if (m_pBeginValues) {
- FX_Free(m_pBeginValues);
- }
- if (m_pEndValues) {
- FX_Free(m_pEndValues);
- }
-}
-FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj)
-{
- CPDF_Dictionary* pDict = pObj->GetDict();
- if (pDict == NULL) {
- return FALSE;
- }
- CPDF_Array* pArray0 = pDict->GetArray(FX_BSTRC("C0"));
- if (m_nOutputs == 0) {
- m_nOutputs = 1;
- if (pArray0) {
- m_nOutputs = pArray0->GetCount();
- }
- }
- CPDF_Array* pArray1 = pDict->GetArray(FX_BSTRC("C1"));
- m_pBeginValues = FX_Alloc(FX_FLOAT, m_nOutputs * 2);
- m_pEndValues = FX_Alloc(FX_FLOAT, m_nOutputs * 2);
- for (int i = 0; i < m_nOutputs; i ++) {
- m_pBeginValues[i] = pArray0 ? pArray0->GetFloat(i) : 0.0f;
- m_pEndValues[i] = pArray1 ? pArray1->GetFloat(i) : 1.0f;
- }
- m_Exponent = pDict->GetFloat(FX_BSTRC("N"));
- m_nOrigOutputs = m_nOutputs;
- if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) {
- return FALSE;
- }
- m_nOutputs *= m_nInputs;
- return TRUE;
-}
-FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const
-{
- for (int i = 0; i < m_nInputs; i ++)
- for (int j = 0; j < m_nOrigOutputs; j ++) {
- results[i * m_nOrigOutputs + j] = m_pBeginValues[j] + (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) *
- (m_pEndValues[j] - m_pBeginValues[j]);
- }
- return TRUE;
-}
-class CPDF_StitchFunc : public CPDF_Function
-{
-public:
- CPDF_StitchFunc();
- virtual ~CPDF_StitchFunc();
- virtual FX_BOOL v_Init(CPDF_Object* pObj);
- virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const;
- int m_nSubs;
- CPDF_Function** m_pSubFunctions;
- FX_FLOAT* m_pBounds;
- FX_FLOAT* m_pEncode;
-};
-CPDF_StitchFunc::CPDF_StitchFunc()
-{
- m_nSubs = 0;
- m_pSubFunctions = NULL;
- m_pBounds = NULL;
- m_pEncode = NULL;
-}
-CPDF_StitchFunc::~CPDF_StitchFunc()
-{
- for (int i = 0; i < m_nSubs; i ++)
- if (m_pSubFunctions[i]) {
- delete m_pSubFunctions[i];
- }
- if (m_pSubFunctions) {
- FX_Free(m_pSubFunctions);
- }
- if (m_pBounds) {
- FX_Free(m_pBounds);
- }
- if (m_pEncode) {
- FX_Free(m_pEncode);
- }
-}
-FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj)
-{
- CPDF_Dictionary* pDict = pObj->GetDict();
- if (pDict == NULL) {
- return FALSE;
- }
- CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions"));
- if (pArray == NULL) {
- return FALSE;
- }
- m_nSubs = pArray->GetCount();
- if (m_nSubs == 0) {
- return FALSE;
- }
- m_pSubFunctions = FX_Alloc(CPDF_Function*, m_nSubs);
- FXSYS_memset32(m_pSubFunctions, 0, sizeof(CPDF_Function*)*m_nSubs);
- m_nOutputs = 0;
- int i;
- for (i = 0; i < m_nSubs; i ++) {
- CPDF_Object* pSub = pArray->GetElementValue(i);
- if (pSub == pObj) {
- return FALSE;
- }
- m_pSubFunctions[i] = CPDF_Function::Load(pSub);
- if (m_pSubFunctions[i] == NULL) {
- return FALSE;
- }
- if (m_pSubFunctions[i]->CountOutputs() > m_nOutputs) {
- m_nOutputs = m_pSubFunctions[i]->CountOutputs();
- }
- }
- m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1);
- m_pBounds[0] = m_pDomains[0];
- pArray = pDict->GetArray(FX_BSTRC("Bounds"));
- if (pArray == NULL) {
- return FALSE;
- }
- for (i = 0; i < m_nSubs - 1; i ++) {
- m_pBounds[i + 1] = pArray->GetFloat(i);
- }
- m_pBounds[m_nSubs] = m_pDomains[1];
- m_pEncode = FX_Alloc(FX_FLOAT, m_nSubs * 2);
- pArray = pDict->GetArray(FX_BSTRC("Encode"));
- if (pArray == NULL) {
- return FALSE;
- }
- for (i = 0; i < m_nSubs * 2; i ++) {
- m_pEncode[i] = pArray->GetFloat(i);
- }
- return TRUE;
-}
-FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const
-{
- FX_FLOAT input = inputs[0];
- int i;
- for (i = 0; i < m_nSubs - 1; i ++)
- if (input < m_pBounds[i + 1]) {
- break;
- }
- if (m_pSubFunctions[i] == NULL) {
- return FALSE;
- }
- input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], m_pEncode[i * 2], m_pEncode[i * 2 + 1]);
- int nresults;
- m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults);
- return TRUE;
-}
-CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj)
-{
- if (pFuncObj == NULL) {
- return NULL;
- }
- CPDF_Function* pFunc = NULL;
- int type;
- if (pFuncObj->GetType() == PDFOBJ_STREAM) {
- type = ((CPDF_Stream*)pFuncObj)->GetDict()->GetInteger(FX_BSTRC("FunctionType"));
- } else if (pFuncObj->GetType() == PDFOBJ_DICTIONARY) {
- type = ((CPDF_Dictionary*)pFuncObj)->GetInteger(FX_BSTRC("FunctionType"));
- } else {
- return NULL;
- }
- if (type == 0) {
- pFunc = FX_NEW CPDF_SampledFunc;
- } else if (type == 2) {
- pFunc = FX_NEW CPDF_ExpIntFunc;
- } else if (type == 3) {
- pFunc = FX_NEW CPDF_StitchFunc;
- } else if (type == 4) {
- pFunc = FX_NEW CPDF_PSFunc;
- } else {
- return NULL;
- }
- if (!pFunc->Init(pFuncObj)) {
- delete pFunc;
- return NULL;
- }
- return pFunc;
-}
-CPDF_Function::CPDF_Function()
-{
- m_pDomains = NULL;
- m_pRanges = NULL;
-}
-CPDF_Function::~CPDF_Function()
-{
- if (m_pDomains) {
- FX_Free(m_pDomains);
- m_pDomains = NULL;
- }
- if (m_pRanges) {
- FX_Free(m_pRanges);
- m_pRanges = NULL;
- }
-}
-FX_BOOL CPDF_Function::Init(CPDF_Object* pObj)
-{
- CPDF_Dictionary* pDict;
- if (pObj->GetType() == PDFOBJ_STREAM) {
- pDict = ((CPDF_Stream*)pObj)->GetDict();
- } else {
- pDict = (CPDF_Dictionary*)pObj;
- }
- CPDF_Array* pDomains = pDict->GetArray(FX_BSTRC("Domain"));
- if (pDomains == NULL) {
- return FALSE;
- }
- m_nInputs = pDomains->GetCount() / 2;
- if (m_nInputs == 0) {
- return FALSE;
- }
- m_pDomains = FX_Alloc(FX_FLOAT, m_nInputs * 2);
- for (int i = 0; i < m_nInputs * 2; i ++) {
- m_pDomains[i] = pDomains->GetFloat(i);
- }
- CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
- m_nOutputs = 0;
- if (pRanges) {
- m_nOutputs = pRanges->GetCount() / 2;
- m_pRanges = FX_Alloc(FX_FLOAT, m_nOutputs * 2);
- for (int i = 0; i < m_nOutputs * 2; i ++) {
- m_pRanges[i] = pRanges->GetFloat(i);
- }
- }
- FX_DWORD old_outputs = m_nOutputs;
- FX_BOOL ret = v_Init(pObj);
- if (m_pRanges && m_nOutputs > (int)old_outputs) {
- m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2);
- if (m_pRanges) {
- FXSYS_memset32(m_pRanges + (old_outputs * 2), 0, sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2);
- }
- }
- return ret;
-}
-FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, int& nresults) const
-{
- if (m_nInputs != ninputs) {
- return FALSE;
- }
- nresults = m_nOutputs;
- for (int i = 0; i < m_nInputs; i ++) {
- if (inputs[i] < m_pDomains[i * 2]) {
- inputs[i] = m_pDomains[i * 2];
- } else if (inputs[i] > m_pDomains[i * 2 + 1]) {
- inputs[i] = m_pDomains[i * 2] + 1;
- }
- }
- v_Call(inputs, results);
- if (m_pRanges) {
- for (int i = 0; i < m_nOutputs; i ++) {
- if (results[i] < m_pRanges[i * 2]) {
- results[i] = m_pRanges[i * 2];
- } else if (results[i] > m_pRanges[i * 2 + 1]) {
- results[i] = m_pRanges[i * 2 + 1];
- }
- }
- }
- return TRUE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "pageint.h" +#include <limits.h> +class CPDF_PSEngine; +typedef enum {PSOP_ADD, PSOP_SUB, PSOP_MUL, PSOP_DIV, PSOP_IDIV, PSOP_MOD, + PSOP_NEG, PSOP_ABS, PSOP_CEILING, PSOP_FLOOR, PSOP_ROUND, PSOP_TRUNCATE, + PSOP_SQRT, PSOP_SIN, PSOP_COS, PSOP_ATAN, PSOP_EXP, PSOP_LN, PSOP_LOG, + PSOP_CVI, PSOP_CVR, PSOP_EQ, PSOP_NE, PSOP_GT, PSOP_GE, PSOP_LT, PSOP_LE, + PSOP_AND, PSOP_OR, PSOP_XOR, PSOP_NOT, PSOP_BITSHIFT, PSOP_TRUE, PSOP_FALSE, + PSOP_IF, PSOP_IFELSE, PSOP_POP, PSOP_EXCH, PSOP_DUP, PSOP_COPY, + PSOP_INDEX, PSOP_ROLL, PSOP_PROC, PSOP_CONST + } PDF_PSOP; +class CPDF_PSProc : public CFX_Object +{ +public: + ~CPDF_PSProc(); + FX_BOOL Parse(CPDF_SimpleParser& parser); + FX_BOOL Execute(CPDF_PSEngine* pEngine); + CFX_PtrArray m_Operators; +}; +#define PSENGINE_STACKSIZE 100 +class CPDF_PSEngine : public CFX_Object +{ +public: + CPDF_PSEngine(); + ~CPDF_PSEngine(); + FX_BOOL Parse(const FX_CHAR* string, int size); + FX_BOOL Execute() + { + return m_MainProc.Execute(this); + } + FX_BOOL DoOperator(PDF_PSOP op); + void Reset() + { + m_StackCount = 0; + } + void Push(FX_FLOAT value); + void Push(int value) + { + Push((FX_FLOAT)value); + } + FX_FLOAT Pop(); + int GetStackSize() + { + return m_StackCount; + } +private: + FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; + int m_StackCount; + CPDF_PSProc m_MainProc; +}; +CPDF_PSProc::~CPDF_PSProc() +{ + int size = m_Operators.GetSize(); + for (int i = 0; i < size; i ++) { + if (m_Operators[i] == (FX_LPVOID)PSOP_PROC) { + delete (CPDF_PSProc*)m_Operators[i + 1]; + i ++; + } else if (m_Operators[i] == (FX_LPVOID)PSOP_CONST) { + FX_Free((FX_FLOAT*)m_Operators[i + 1]); + i ++; + } + } +} +#pragma optimize( "", off ) +FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) +{ + int size = m_Operators.GetSize(); + for (int i = 0; i < size; i ++) { + PDF_PSOP op = (PDF_PSOP)(FX_UINTPTR)m_Operators[i]; + if (op == PSOP_PROC) { + i ++; + } else if (op == PSOP_CONST) { + pEngine->Push(*(FX_FLOAT*)m_Operators[i + 1]); + i ++; + } else if (op == PSOP_IF) { + if (i < 2 || m_Operators[i - 2] != (FX_LPVOID)PSOP_PROC) { + return FALSE; + } + if ((int)pEngine->Pop()) { + ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine); + } + } else if (op == PSOP_IFELSE) { + if (i < 4 || m_Operators[i - 2] != (FX_LPVOID)PSOP_PROC || + m_Operators[i - 4] != (FX_LPVOID)PSOP_PROC) { + return FALSE; + } + if ((int)pEngine->Pop()) { + ((CPDF_PSProc*)m_Operators[i - 3])->Execute(pEngine); + } else { + ((CPDF_PSProc*)m_Operators[i - 1])->Execute(pEngine); + } + } else { + pEngine->DoOperator(op); + } + } + return TRUE; +} +#pragma optimize( "", on ) +CPDF_PSEngine::CPDF_PSEngine() +{ + m_StackCount = 0; +} +CPDF_PSEngine::~CPDF_PSEngine() +{ +} +void CPDF_PSEngine::Push(FX_FLOAT v) +{ + if (m_StackCount == 100) { + return; + } + m_Stack[m_StackCount++] = v; +} +FX_FLOAT CPDF_PSEngine::Pop() +{ + if (m_StackCount == 0) { + return 0; + } + return m_Stack[--m_StackCount]; +} +const struct _PDF_PSOpName { + const FX_CHAR* name; + PDF_PSOP op; +} _PDF_PSOpNames[] = { + {"add", PSOP_ADD}, {"sub", PSOP_SUB}, {"mul", PSOP_MUL}, {"div", PSOP_DIV}, + {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD}, {"neg", PSOP_NEG}, {"abs", PSOP_ABS}, + {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR}, {"round", PSOP_ROUND}, + {"truncate", PSOP_TRUNCATE}, {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN}, + {"cos", PSOP_COS}, {"atan", PSOP_ATAN}, {"exp", PSOP_EXP}, {"ln", PSOP_LN}, + {"log", PSOP_LOG}, {"cvi", PSOP_CVI}, {"cvr", PSOP_CVR}, {"eq", PSOP_EQ}, + {"ne", PSOP_NE}, {"gt", PSOP_GT}, {"ge", PSOP_GE}, {"lt", PSOP_LT}, + {"le", PSOP_LE}, {"and", PSOP_AND}, {"or", PSOP_OR}, {"xor", PSOP_XOR}, + {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT}, {"true", PSOP_TRUE}, + {"false", PSOP_FALSE}, {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE}, + {"pop", PSOP_POP}, {"exch", PSOP_EXCH}, {"dup", PSOP_DUP}, + {"copy", PSOP_COPY}, {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}, + {NULL, PSOP_PROC} +}; +FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* string, int size) +{ + CPDF_SimpleParser parser((FX_LPBYTE)string, size); + CFX_ByteStringC word = parser.GetWord(); + if (word != FX_BSTRC("{")) { + return FALSE; + } + return m_MainProc.Parse(parser); +} +FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser& parser) +{ + while (1) { + CFX_ByteStringC word = parser.GetWord(); + if (word.IsEmpty()) { + return FALSE; + } + if (word == FX_BSTRC("}")) { + return TRUE; + } + if (word == FX_BSTRC("{")) { + CPDF_PSProc* pProc = FX_NEW CPDF_PSProc; + m_Operators.Add((FX_LPVOID)PSOP_PROC); + m_Operators.Add(pProc); + if (!pProc->Parse(parser)) { + return FALSE; + } + } else { + int i = 0; + while (_PDF_PSOpNames[i].name) { + if (word == CFX_ByteStringC(_PDF_PSOpNames[i].name)) { + m_Operators.Add((FX_LPVOID)_PDF_PSOpNames[i].op); + break; + } + i ++; + } + if (_PDF_PSOpNames[i].name == NULL) { + FX_FLOAT* pd = FX_Alloc(FX_FLOAT, 1); + *pd = FX_atof(word); + m_Operators.Add((FX_LPVOID)PSOP_CONST); + m_Operators.Add(pd); + } + } + } +} +#define PI 3.1415926535897932384626433832795f +FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) +{ + int i1, i2; + FX_FLOAT d1, d2; + switch (op) { + case PSOP_ADD: + d1 = Pop(); + d2 = Pop(); + Push(d1 + d2); + break; + case PSOP_SUB: + d2 = Pop(); + d1 = Pop(); + Push(d1 - d2); + break; + case PSOP_MUL: + d1 = Pop(); + d2 = Pop(); + Push(d1 * d2); + break; + case PSOP_DIV: + d2 = Pop(); + d1 = Pop(); + Push(d1 / d2); + break; + case PSOP_IDIV: + i2 = (int)Pop(); + i1 = (int)Pop(); + Push(i1 / i2); + break; + case PSOP_MOD: + i2 = (int)Pop(); + i1 = (int)Pop(); + Push(i1 % i2); + break; + case PSOP_NEG: + d1 = Pop(); + Push(-d1); + break; + case PSOP_ABS: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_fabs(d1)); + break; + case PSOP_CEILING: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_ceil(d1)); + break; + case PSOP_FLOOR: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_floor(d1)); + break; + case PSOP_ROUND: + d1 = Pop(); + Push(FXSYS_round(d1)); + break; + case PSOP_TRUNCATE: + i1 = (int)Pop(); + Push(i1); + break; + case PSOP_SQRT: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_sqrt(d1)); + break; + case PSOP_SIN: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_sin(d1 * PI / 180.0f)); + break; + case PSOP_COS: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_cos(d1 * PI / 180.0f)); + break; + case PSOP_ATAN: + d2 = Pop(); + d1 = Pop(); + d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / PI); + if (d1 < 0) { + d1 += 360; + } + Push(d1); + break; + case PSOP_EXP: + d2 = Pop(); + d1 = Pop(); + Push((FX_FLOAT)FXSYS_pow(d1, d2)); + break; + case PSOP_LN: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_log(d1)); + break; + case PSOP_LOG: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_log10(d1)); + break; + case PSOP_CVI: + i1 = (int)Pop(); + Push(i1); + break; + case PSOP_CVR: + break; + case PSOP_EQ: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 == d2)); + break; + case PSOP_NE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 != d2)); + break; + case PSOP_GT: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 > d2)); + break; + case PSOP_GE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 >= d2)); + break; + case PSOP_LT: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 < d2)); + break; + case PSOP_LE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 <= d2)); + break; + case PSOP_AND: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 & i2); + break; + case PSOP_OR: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 | i2); + break; + case PSOP_XOR: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 ^ i2); + break; + case PSOP_NOT: + i1 = (int)Pop(); + Push((int)!i1); + break; + case PSOP_BITSHIFT: { + int shift = (int)Pop(); + int i = (int)Pop(); + if (shift > 0) { + Push(i << shift); + } else { + Push(i >> -shift); + } + break; + } + case PSOP_TRUE: + Push(1); + break; + case PSOP_FALSE: + Push(0); + break; + case PSOP_POP: + Pop(); + break; + case PSOP_EXCH: + d2 = Pop(); + d1 = Pop(); + Push(d2); + Push(d1); + break; + case PSOP_DUP: + d1 = Pop(); + Push(d1); + Push(d1); + break; + case PSOP_COPY: { + int n = (int)Pop(); + if (n < 0 || n > PSENGINE_STACKSIZE || m_StackCount + n > PSENGINE_STACKSIZE || n > m_StackCount) { + break; + } + for (int i = 0; i < n; i ++) { + m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; + } + m_StackCount += n; + break; + } + case PSOP_INDEX: { + int n = (int)Pop(); + if (n < 0 || n >= m_StackCount) { + break; + } + Push(m_Stack[m_StackCount - n - 1]); + break; + } + case PSOP_ROLL: { + int j = (int)Pop(); + int n = (int)Pop(); + if (m_StackCount == 0) { + break; + } + if (n < 0 || n > m_StackCount) { + break; + } + if (j < 0) + for (int i = 0; i < -j; i ++) { + FX_FLOAT first = m_Stack[m_StackCount - n]; + for (int ii = 0; ii < n - 1; ii ++) { + m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; + } + m_Stack[m_StackCount - 1] = first; + } + else + for (int i = 0; i < j; i ++) { + FX_FLOAT last = m_Stack[m_StackCount - 1]; + int ii; + for (ii = 0; ii < n - 1; ii ++) { + m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; + } + m_Stack[m_StackCount - ii - 1] = last; + } + break; + } + default: + break; + } + return TRUE; +} +static FX_FLOAT PDF_Interpolate(FX_FLOAT x, FX_FLOAT xmin, FX_FLOAT xmax, FX_FLOAT ymin, FX_FLOAT ymax) +{ + return ((x - xmin) * (ymax - ymin) / (xmax - xmin)) + ymin; +} +static FX_DWORD _GetBits32(FX_LPCBYTE pData, int bitpos, int nbits) +{ + int result = 0; + for (int i = 0; i < nbits; i ++) + if (pData[(bitpos + i) / 8] & (1 << (7 - (bitpos + i) % 8))) { + result |= 1 << (nbits - i - 1); + } + return result; +} +typedef struct { + FX_FLOAT encode_max, encode_min; + int sizes; +} SampleEncodeInfo; +typedef struct { + FX_FLOAT decode_max, decode_min; +} SampleDecodeInfo; +class CPDF_SampledFunc : public CPDF_Function +{ +public: + CPDF_SampledFunc(); + virtual ~CPDF_SampledFunc(); + virtual FX_BOOL v_Init(CPDF_Object* pObj); + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const; + SampleEncodeInfo* m_pEncodeInfo; + SampleDecodeInfo* m_pDecodeInfo; + FX_DWORD m_nBitsPerSample, m_SampleMax; + CPDF_StreamAcc* m_pSampleStream; +}; +CPDF_SampledFunc::CPDF_SampledFunc() +{ + m_pSampleStream = NULL; + m_pEncodeInfo = NULL; + m_pDecodeInfo = NULL; +} +CPDF_SampledFunc::~CPDF_SampledFunc() +{ + if (m_pSampleStream) { + delete m_pSampleStream; + } + if (m_pEncodeInfo) { + FX_Free(m_pEncodeInfo); + } + if (m_pDecodeInfo) { + FX_Free(m_pDecodeInfo); + } +} +FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) +{ + if (pObj->GetType() != PDFOBJ_STREAM) { + return FALSE; + } + CPDF_Stream* pStream = (CPDF_Stream*)pObj; + CPDF_Dictionary* pDict = pStream->GetDict(); + CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size")); + CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode")); + CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode")); + m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample")); + m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); + m_pSampleStream = FX_NEW CPDF_StreamAcc; + m_pSampleStream->LoadAllData(pStream, FALSE); + m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); + int i; + FX_DWORD nTotalSamples = 1; + for (i = 0; i < m_nInputs; i ++) { + m_pEncodeInfo[i].sizes = pSize->GetInteger(i); + if (!pSize && i == 0) { + m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size")); + } + if (nTotalSamples > 0 && (FX_UINT32)(m_pEncodeInfo[i].sizes) > UINT_MAX / nTotalSamples) { + return FALSE; + } + nTotalSamples *= m_pEncodeInfo[i].sizes; + if (pEncode) { + m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2); + m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1); + } else { + m_pEncodeInfo[i].encode_min = 0; + if (m_pEncodeInfo[i].sizes == 1) { + m_pEncodeInfo[i].encode_max = 1; + } else { + m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; + } + } + } + if (nTotalSamples > 0 && m_nBitsPerSample > UINT_MAX / nTotalSamples) { + return FALSE; + } + nTotalSamples *= m_nBitsPerSample; + if (nTotalSamples > 0 && ((FX_UINT32)m_nOutputs) > UINT_MAX / nTotalSamples) { + return FALSE; + } + nTotalSamples *= m_nOutputs; + if (nTotalSamples == 0 || m_pSampleStream->GetSize() * 8 < nTotalSamples) { + return FALSE; + } + m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); + for (i = 0; i < m_nOutputs; i ++) { + if (pDecode) { + m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i); + m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1); + } else { + m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; + m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; + } + } + return TRUE; +} +FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const +{ + int pos = 0; + CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs); + FX_FLOAT* encoded_input = encoded_input_buf; + CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2); + int* index = int_buf; + int* blocksize = index + m_nInputs; + for (int i = 0; i < m_nInputs; i ++) { + if (i == 0) { + blocksize[i] = 1; + } else { + blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes; + } + encoded_input[i] = PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], + m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max); + index[i] = (int)encoded_input[i]; + if (index[i] < 0) { + index[i] = 0; + } else if (index[i] > m_pEncodeInfo[i].sizes - 1) { + index[i] = m_pEncodeInfo[i].sizes - 1; + } + pos += index[i] * blocksize[i]; + } + int bitpos = pos * m_nBitsPerSample * m_nOutputs; + FX_LPCBYTE pSampleData = m_pSampleStream->GetData(); + if (pSampleData == NULL) { + return FALSE; + } + for (int j = 0; j < m_nOutputs; j ++) { + FX_DWORD sample = _GetBits32(pSampleData, bitpos + j * m_nBitsPerSample, m_nBitsPerSample); + FX_FLOAT encoded = (FX_FLOAT)sample; + for (int i = 0; i < m_nInputs; i ++) { + if (index[i] == m_pEncodeInfo[i].sizes - 1) { + if (index[i] == 0) { + encoded = encoded_input[i] * (FX_FLOAT)sample; + } + } else { + int bitpos1 = bitpos + m_nBitsPerSample * m_nOutputs * blocksize[i]; + FX_DWORD sample1 = _GetBits32(pSampleData, bitpos1 + j * m_nBitsPerSample, m_nBitsPerSample); + encoded += (encoded_input[i] - index[i]) * ((FX_FLOAT)sample1 - (FX_FLOAT)sample); + } + } + results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, + m_pDecodeInfo[j].decode_min, m_pDecodeInfo[j].decode_max); + } + return TRUE; +} +class CPDF_PSFunc : public CPDF_Function +{ +public: + virtual FX_BOOL v_Init(CPDF_Object* pObj); + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const; + CPDF_PSEngine m_PS; +}; +FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) +{ + CPDF_Stream* pStream = (CPDF_Stream*)pObj; + CPDF_StreamAcc acc; + acc.LoadAllData(pStream, FALSE); + return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize()); +} +FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const +{ + CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS; + PS.Reset(); + int i; + for (i = 0; i < m_nInputs; i ++) { + PS.Push(inputs[i]); + } + PS.Execute(); + if (PS.GetStackSize() < m_nOutputs) { + return FALSE; + } + for (i = 0; i < m_nOutputs; i ++) { + results[m_nOutputs - i - 1] = PS.Pop(); + } + return TRUE; +} +class CPDF_ExpIntFunc : public CPDF_Function +{ +public: + CPDF_ExpIntFunc(); + virtual ~CPDF_ExpIntFunc(); + virtual FX_BOOL v_Init(CPDF_Object* pObj); + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const; + FX_FLOAT m_Exponent; + FX_FLOAT* m_pBeginValues; + FX_FLOAT* m_pEndValues; + int m_nOrigOutputs; +}; +CPDF_ExpIntFunc::CPDF_ExpIntFunc() +{ + m_pBeginValues = NULL; + m_pEndValues = NULL; +} +CPDF_ExpIntFunc::~CPDF_ExpIntFunc() +{ + if (m_pBeginValues) { + FX_Free(m_pBeginValues); + } + if (m_pEndValues) { + FX_Free(m_pEndValues); + } +} +FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) +{ + CPDF_Dictionary* pDict = pObj->GetDict(); + if (pDict == NULL) { + return FALSE; + } + CPDF_Array* pArray0 = pDict->GetArray(FX_BSTRC("C0")); + if (m_nOutputs == 0) { + m_nOutputs = 1; + if (pArray0) { + m_nOutputs = pArray0->GetCount(); + } + } + CPDF_Array* pArray1 = pDict->GetArray(FX_BSTRC("C1")); + m_pBeginValues = FX_Alloc(FX_FLOAT, m_nOutputs * 2); + m_pEndValues = FX_Alloc(FX_FLOAT, m_nOutputs * 2); + for (int i = 0; i < m_nOutputs; i ++) { + m_pBeginValues[i] = pArray0 ? pArray0->GetFloat(i) : 0.0f; + m_pEndValues[i] = pArray1 ? pArray1->GetFloat(i) : 1.0f; + } + m_Exponent = pDict->GetFloat(FX_BSTRC("N")); + m_nOrigOutputs = m_nOutputs; + if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { + return FALSE; + } + m_nOutputs *= m_nInputs; + return TRUE; +} +FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const +{ + for (int i = 0; i < m_nInputs; i ++) + for (int j = 0; j < m_nOrigOutputs; j ++) { + results[i * m_nOrigOutputs + j] = m_pBeginValues[j] + (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * + (m_pEndValues[j] - m_pBeginValues[j]); + } + return TRUE; +} +class CPDF_StitchFunc : public CPDF_Function +{ +public: + CPDF_StitchFunc(); + virtual ~CPDF_StitchFunc(); + virtual FX_BOOL v_Init(CPDF_Object* pObj); + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const; + int m_nSubs; + CPDF_Function** m_pSubFunctions; + FX_FLOAT* m_pBounds; + FX_FLOAT* m_pEncode; +}; +CPDF_StitchFunc::CPDF_StitchFunc() +{ + m_nSubs = 0; + m_pSubFunctions = NULL; + m_pBounds = NULL; + m_pEncode = NULL; +} +CPDF_StitchFunc::~CPDF_StitchFunc() +{ + for (int i = 0; i < m_nSubs; i ++) + if (m_pSubFunctions[i]) { + delete m_pSubFunctions[i]; + } + if (m_pSubFunctions) { + FX_Free(m_pSubFunctions); + } + if (m_pBounds) { + FX_Free(m_pBounds); + } + if (m_pEncode) { + FX_Free(m_pEncode); + } +} +FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) +{ + CPDF_Dictionary* pDict = pObj->GetDict(); + if (pDict == NULL) { + return FALSE; + } + CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions")); + if (pArray == NULL) { + return FALSE; + } + m_nSubs = pArray->GetCount(); + if (m_nSubs == 0) { + return FALSE; + } + m_pSubFunctions = FX_Alloc(CPDF_Function*, m_nSubs); + FXSYS_memset32(m_pSubFunctions, 0, sizeof(CPDF_Function*)*m_nSubs); + m_nOutputs = 0; + int i; + for (i = 0; i < m_nSubs; i ++) { + CPDF_Object* pSub = pArray->GetElementValue(i); + if (pSub == pObj) { + return FALSE; + } + m_pSubFunctions[i] = CPDF_Function::Load(pSub); + if (m_pSubFunctions[i] == NULL) { + return FALSE; + } + if (m_pSubFunctions[i]->CountOutputs() > m_nOutputs) { + m_nOutputs = m_pSubFunctions[i]->CountOutputs(); + } + } + m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1); + m_pBounds[0] = m_pDomains[0]; + pArray = pDict->GetArray(FX_BSTRC("Bounds")); + if (pArray == NULL) { + return FALSE; + } + for (i = 0; i < m_nSubs - 1; i ++) { + m_pBounds[i + 1] = pArray->GetFloat(i); + } + m_pBounds[m_nSubs] = m_pDomains[1]; + m_pEncode = FX_Alloc(FX_FLOAT, m_nSubs * 2); + pArray = pDict->GetArray(FX_BSTRC("Encode")); + if (pArray == NULL) { + return FALSE; + } + for (i = 0; i < m_nSubs * 2; i ++) { + m_pEncode[i] = pArray->GetFloat(i); + } + return TRUE; +} +FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const +{ + FX_FLOAT input = inputs[0]; + int i; + for (i = 0; i < m_nSubs - 1; i ++) + if (input < m_pBounds[i + 1]) { + break; + } + if (m_pSubFunctions[i] == NULL) { + return FALSE; + } + input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], m_pEncode[i * 2], m_pEncode[i * 2 + 1]); + int nresults; + m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults); + return TRUE; +} +CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) +{ + if (pFuncObj == NULL) { + return NULL; + } + CPDF_Function* pFunc = NULL; + int type; + if (pFuncObj->GetType() == PDFOBJ_STREAM) { + type = ((CPDF_Stream*)pFuncObj)->GetDict()->GetInteger(FX_BSTRC("FunctionType")); + } else if (pFuncObj->GetType() == PDFOBJ_DICTIONARY) { + type = ((CPDF_Dictionary*)pFuncObj)->GetInteger(FX_BSTRC("FunctionType")); + } else { + return NULL; + } + if (type == 0) { + pFunc = FX_NEW CPDF_SampledFunc; + } else if (type == 2) { + pFunc = FX_NEW CPDF_ExpIntFunc; + } else if (type == 3) { + pFunc = FX_NEW CPDF_StitchFunc; + } else if (type == 4) { + pFunc = FX_NEW CPDF_PSFunc; + } else { + return NULL; + } + if (!pFunc->Init(pFuncObj)) { + delete pFunc; + return NULL; + } + return pFunc; +} +CPDF_Function::CPDF_Function() +{ + m_pDomains = NULL; + m_pRanges = NULL; +} +CPDF_Function::~CPDF_Function() +{ + if (m_pDomains) { + FX_Free(m_pDomains); + m_pDomains = NULL; + } + if (m_pRanges) { + FX_Free(m_pRanges); + m_pRanges = NULL; + } +} +FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) +{ + CPDF_Dictionary* pDict; + if (pObj->GetType() == PDFOBJ_STREAM) { + pDict = ((CPDF_Stream*)pObj)->GetDict(); + } else { + pDict = (CPDF_Dictionary*)pObj; + } + CPDF_Array* pDomains = pDict->GetArray(FX_BSTRC("Domain")); + if (pDomains == NULL) { + return FALSE; + } + m_nInputs = pDomains->GetCount() / 2; + if (m_nInputs == 0) { + return FALSE; + } + m_pDomains = FX_Alloc(FX_FLOAT, m_nInputs * 2); + for (int i = 0; i < m_nInputs * 2; i ++) { + m_pDomains[i] = pDomains->GetFloat(i); + } + CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range")); + m_nOutputs = 0; + if (pRanges) { + m_nOutputs = pRanges->GetCount() / 2; + m_pRanges = FX_Alloc(FX_FLOAT, m_nOutputs * 2); + for (int i = 0; i < m_nOutputs * 2; i ++) { + m_pRanges[i] = pRanges->GetFloat(i); + } + } + FX_DWORD old_outputs = m_nOutputs; + FX_BOOL ret = v_Init(pObj); + if (m_pRanges && m_nOutputs > (int)old_outputs) { + m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); + if (m_pRanges) { + FXSYS_memset32(m_pRanges + (old_outputs * 2), 0, sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); + } + } + return ret; +} +FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, int& nresults) const +{ + if (m_nInputs != ninputs) { + return FALSE; + } + nresults = m_nOutputs; + for (int i = 0; i < m_nInputs; i ++) { + if (inputs[i] < m_pDomains[i * 2]) { + inputs[i] = m_pDomains[i * 2]; + } else if (inputs[i] > m_pDomains[i * 2 + 1]) { + inputs[i] = m_pDomains[i * 2] + 1; + } + } + v_Call(inputs, results); + if (m_pRanges) { + for (int i = 0; i < m_nOutputs; i ++) { + if (results[i] < m_pRanges[i * 2]) { + results[i] = m_pRanges[i * 2]; + } else if (results[i] > m_pRanges[i * 2 + 1]) { + results[i] = m_pRanges[i * 2 + 1]; + } + } + } + return TRUE; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp index e9115e6342..f53a5b23a4 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp @@ -1,707 +1,707 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_pageobj.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fpdfapi/fpdf_render.h"
-#include "pageint.h"
-#include "../fpdf_render/render_int.h"
-void CPDF_GraphicStates::DefaultStates()
-{
- m_ColorState.New()->Default();
-}
-void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src)
-{
- m_ClipPath = src.m_ClipPath;
- m_GraphState = src.m_GraphState;
- m_ColorState = src.m_ColorState;
- m_TextState = src.m_TextState;
- m_GeneralState = src.m_GeneralState;
-}
-CPDF_ClipPathData::CPDF_ClipPathData()
-{
- m_PathCount = 0;
- m_pPathList = NULL;
- m_pTypeList = NULL;
- m_TextCount = 0;
- m_pTextList = NULL;
-}
-CPDF_ClipPathData::~CPDF_ClipPathData()
-{
- int i;
- if (m_pPathList) {
- FX_DELETE_VECTOR(m_pPathList, CPDF_Path, m_PathCount);
- }
- if (m_pTypeList) {
- FX_Free(m_pTypeList);
- }
- for (i = m_TextCount - 1; i > -1; i --)
- if (m_pTextList[i]) {
- delete m_pTextList[i];
- }
- if (m_pTextList) {
- FX_Free(m_pTextList);
- }
-}
-CPDF_ClipPathData::CPDF_ClipPathData(const CPDF_ClipPathData& src)
-{
- m_pPathList = NULL;
- m_pPathList = NULL;
- m_pTextList = NULL;
- m_PathCount = src.m_PathCount;
- if (m_PathCount) {
- int alloc_size = m_PathCount;
- if (alloc_size % 8) {
- alloc_size += 8 - (alloc_size % 8);
- }
- FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size);
- for (int i = 0; i < m_PathCount; i ++) {
- m_pPathList[i] = src.m_pPathList[i];
- }
- m_pTypeList = FX_Alloc(FX_BYTE, alloc_size);
- FXSYS_memcpy32(m_pTypeList, src.m_pTypeList, m_PathCount);
- } else {
- m_pPathList = NULL;
- m_pTypeList = NULL;
- }
- m_TextCount = src.m_TextCount;
- if (m_TextCount) {
- m_pTextList = FX_Alloc(CPDF_TextObject*, m_TextCount);
- FXSYS_memset32(m_pTextList, 0, sizeof(CPDF_TextObject*) * m_TextCount);
- for (int i = 0; i < m_TextCount; i ++) {
- if (src.m_pTextList[i]) {
- m_pTextList[i] = FX_NEW CPDF_TextObject;
- m_pTextList[i]->Copy(src.m_pTextList[i]);
- } else {
- m_pTextList[i] = NULL;
- }
- }
- } else {
- m_pTextList = NULL;
- }
-}
-void CPDF_ClipPathData::SetCount(int path_count, int text_count)
-{
- ASSERT(m_TextCount == 0 && m_PathCount == 0);
- if (path_count) {
- m_PathCount = path_count;
- int alloc_size = (path_count + 7) / 8 * 8;
- FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size);
- m_pTypeList = FX_Alloc(FX_BYTE, alloc_size);
- }
- if (text_count) {
- m_TextCount = text_count;
- m_pTextList = FX_Alloc(CPDF_TextObject*, text_count);
- FXSYS_memset32(m_pTextList, 0, sizeof(void*) * text_count);
- }
-}
-CPDF_Rect CPDF_ClipPath::GetClipBox() const
-{
- CPDF_Rect rect;
- FX_BOOL bStarted = FALSE;
- int count = GetPathCount();
- if (count) {
- rect = GetPath(0).GetBoundingBox();
- for (int i = 1; i < count; i ++) {
- CPDF_Rect path_rect = GetPath(i).GetBoundingBox();
- rect.Intersect(path_rect);
- }
- bStarted = TRUE;
- }
- count = GetTextCount();
- if (count) {
- CPDF_Rect layer_rect;
- FX_BOOL bLayerStarted = FALSE;
- for (int i = 0; i < count; i ++) {
- CPDF_TextObject* pTextObj = GetText(i);
- if (pTextObj == NULL) {
- if (!bStarted) {
- rect = layer_rect;
- bStarted = TRUE;
- } else {
- rect.Intersect(layer_rect);
- }
- bLayerStarted = FALSE;
- } else {
- if (!bLayerStarted) {
- layer_rect = pTextObj->GetBBox(NULL);
- bLayerStarted = TRUE;
- } else {
- layer_rect.Union(pTextObj->GetBBox(NULL));
- }
- }
- }
- }
- return rect;
-}
-void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge)
-{
- CPDF_ClipPathData* pData = GetModify();
- if (pData->m_PathCount && bAutoMerge) {
- CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1];
- if (old_path.IsRect()) {
- CPDF_Rect old_rect(old_path.GetPointX(0), old_path.GetPointY(0),
- old_path.GetPointX(2), old_path.GetPointY(2));
- CPDF_Rect new_rect = path.GetBoundingBox();
- if (old_rect.Contains(new_rect)) {
- pData->m_PathCount --;
- pData->m_pPathList[pData->m_PathCount].SetNull();
- }
- }
- }
- if (pData->m_PathCount % 8 == 0) {
- CPDF_Path* pNewPath;
- FX_NEW_VECTOR(pNewPath, CPDF_Path, pData->m_PathCount + 8);
- for (int i = 0; i < pData->m_PathCount; i ++) {
- pNewPath[i] = pData->m_pPathList[i];
- }
- if (pData->m_pPathList) {
- FX_DELETE_VECTOR(pData->m_pPathList, CPDF_Path, pData->m_PathCount);
- }
- FX_BYTE* pNewType = FX_Alloc(FX_BYTE, pData->m_PathCount + 8);
- FXSYS_memcpy32(pNewType, pData->m_pTypeList, pData->m_PathCount);
- if (pData->m_pTypeList) {
- FX_Free(pData->m_pTypeList);
- }
- pData->m_pPathList = pNewPath;
- pData->m_pTypeList = pNewType;
- }
- pData->m_pPathList[pData->m_PathCount] = path;
- pData->m_pTypeList[pData->m_PathCount] = (FX_BYTE)type;
- pData->m_PathCount ++;
-}
-void CPDF_ClipPath::DeletePath(int index)
-{
- CPDF_ClipPathData* pData = GetModify();
- if (index >= pData->m_PathCount) {
- return;
- }
- pData->m_pPathList[index].SetNull();
- for (int i = index; i < pData->m_PathCount - 1; i ++) {
- pData->m_pPathList[i] = pData->m_pPathList[i + 1];
- }
- pData->m_pPathList[pData->m_PathCount - 1].SetNull();
- FXSYS_memmove32(pData->m_pTypeList + index, pData->m_pTypeList + index + 1, pData->m_PathCount - index - 1);
- pData->m_PathCount --;
-}
-#define FPDF_CLIPPATH_MAX_TEXTS 1024
-void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count)
-{
- CPDF_ClipPathData* pData = GetModify();
- if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) {
- for (int i = 0; i < count; i ++) {
- pTexts[i]->Release();
- }
- return;
- }
- CPDF_TextObject** pNewList = FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1);
- if (pData->m_pTextList) {
- FXSYS_memcpy32(pNewList, pData->m_pTextList, pData->m_TextCount * sizeof(CPDF_TextObject*));
- FX_Free(pData->m_pTextList);
- }
- pData->m_pTextList = pNewList;
- for (int i = 0; i < count; i ++) {
- pData->m_pTextList[pData->m_TextCount + i] = pTexts[i];
- }
- pData->m_pTextList[pData->m_TextCount + count] = NULL;
- pData->m_TextCount += count + 1;
-}
-void CPDF_ClipPath::Transform(const CPDF_Matrix& matrix)
-{
- CPDF_ClipPathData* pData = GetModify();
- int i;
- for (i = 0; i < pData->m_PathCount; i ++) {
- pData->m_pPathList[i].Transform(&matrix);
- }
- for (i = 0; i < pData->m_TextCount; i ++)
- if (pData->m_pTextList[i]) {
- pData->m_pTextList[i]->Transform(matrix);
- }
-}
-CPDF_ColorStateData::CPDF_ColorStateData(const CPDF_ColorStateData& src)
-{
- m_FillColor.Copy(&src.m_FillColor);
- m_FillRGB = src.m_FillRGB;
- m_StrokeColor.Copy(&src.m_StrokeColor);
- m_StrokeRGB = src.m_StrokeRGB;
-}
-void CPDF_ColorStateData::Default()
-{
- m_FillRGB = m_StrokeRGB = 0;
- m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
- m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
-}
-void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
-{
- CPDF_ColorStateData* pData = GetModify();
- SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues);
-}
-void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
-{
- CPDF_ColorStateData* pData = GetModify();
- SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues);
-}
-void CPDF_ColorState::SetColor(CPDF_Color& color, FX_DWORD& rgb, CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues)
-{
- if (pCS) {
- color.SetColorSpace(pCS);
- } else if (color.IsNull()) {
- color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
- }
- if (color.m_pCS->CountComponents() > nValues) {
- return;
- }
- color.SetValue(pValue);
- int R, G, B;
- rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
-}
-void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues)
-{
- CPDF_ColorStateData* pData = GetModify();
- pData->m_FillColor.SetValue(pPattern, pValue, nValues);
- int R, G, B;
- FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B);
- if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
- pData->m_FillRGB = 0x00BFBFBF;
- return;
- }
- pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
-}
-void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues)
-{
- CPDF_ColorStateData* pData = GetModify();
- pData->m_StrokeColor.SetValue(pPattern, pValue, nValues);
- int R, G, B;
- FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B);
- if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
- pData->m_StrokeRGB = 0x00BFBFBF;
- return;
- }
- pData->m_StrokeRGB = pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1;
-}
-CPDF_TextStateData::CPDF_TextStateData()
-{
- m_pFont = NULL;
- m_FontSize = 1.0f;
- m_WordSpace = 0;
- m_CharSpace = 0;
- m_TextMode = 0;
- m_Matrix[0] = m_Matrix[3] = 1.0f;
- m_Matrix[1] = m_Matrix[2] = 0;
- m_CTM[0] = m_CTM[3] = 1.0f;
- m_CTM[1] = m_CTM[2] = 0;
-}
-CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src)
-{
- FXSYS_memcpy32(this, &src, sizeof(CPDF_TextStateData));
- if (m_pFont && m_pFont->m_pDocument) {
- m_pFont = m_pFont->m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE);
- }
-}
-CPDF_TextStateData::~CPDF_TextStateData()
-{
- CPDF_Font* pFont = m_pFont;
- if (pFont && pFont->m_pDocument) {
- pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict());
- }
-}
-void CPDF_TextState::SetFont(CPDF_Font* pFont)
-{
- CPDF_Font*& pStateFont = GetModify()->m_pFont;
- CPDF_DocPageData* pDocPageData = NULL;
- if (pStateFont && pStateFont->m_pDocument) {
- pDocPageData = pStateFont->m_pDocument->GetPageData();
- pDocPageData->ReleaseFont(pStateFont->GetFontDict());
- }
- pStateFont = pFont;
-}
-FX_FLOAT CPDF_TextState::GetFontSizeV() const
-{
- FX_FLOAT* pMatrix = GetMatrix();
- FX_FLOAT unit = FXSYS_sqrt2(pMatrix[1], pMatrix[3]);
- FX_FLOAT size = FXSYS_Mul(unit, GetFontSize());
- return (FX_FLOAT)FXSYS_fabs(size);
-}
-FX_FLOAT CPDF_TextState::GetFontSizeH() const
-{
- FX_FLOAT* pMatrix = GetMatrix();
- FX_FLOAT unit = FXSYS_sqrt2(pMatrix[0], pMatrix[2]);
- FX_FLOAT size = FXSYS_Mul(unit, GetFontSize());
- return (FX_FLOAT)FXSYS_fabs(size);
-}
-FX_FLOAT CPDF_TextState::GetBaselineAngle() const
-{
- FX_FLOAT* m_Matrix = GetMatrix();
- return FXSYS_atan2(m_Matrix[2], m_Matrix[0]);
-}
-FX_FLOAT CPDF_TextState::GetShearAngle() const
-{
- FX_FLOAT* m_Matrix = GetMatrix();
- FX_FLOAT shear_angle = FXSYS_atan2(m_Matrix[1], m_Matrix[3]);
- return GetBaselineAngle() + shear_angle;
-}
-CPDF_GeneralStateData::CPDF_GeneralStateData()
-{
- FXSYS_memset32(this, 0, sizeof(CPDF_GeneralStateData));
- FXSYS_strcpy((FX_LPSTR)m_BlendMode, (FX_LPCSTR)"Normal");
- m_StrokeAlpha = 1.0f;
- m_FillAlpha = 1.0f;
- m_Flatness = 1.0f;
- m_Matrix.SetIdentity();
-}
-CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src)
-{
- FXSYS_memcpy32(this, &src, sizeof(CPDF_GeneralStateData));
- if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) {
- CPDF_DocRenderData* pDocCache = src.m_pTransferFunc->m_pPDFDoc->GetRenderData();
- if (!pDocCache) {
- return;
- }
- m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
- }
-}
-CPDF_GeneralStateData::~CPDF_GeneralStateData()
-{
- if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
- CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
- if (!pDocCache) {
- return;
- }
- pDocCache->ReleaseTransferFunc(m_pTR);
- }
-}
-static int GetBlendType(FX_BSTR mode)
-{
- switch (mode.GetID()) {
- case FXBSTR_ID('N', 'o', 'r', 'm'):
- case FXBSTR_ID('C', 'o', 'm', 'p'):
- return FXDIB_BLEND_NORMAL;
- case FXBSTR_ID('M', 'u', 'l', 't'):
- return FXDIB_BLEND_MULTIPLY;
- case FXBSTR_ID('S', 'c', 'r', 'e'):
- return FXDIB_BLEND_SCREEN;
- case FXBSTR_ID('O', 'v', 'e', 'r'):
- return FXDIB_BLEND_OVERLAY;
- case FXBSTR_ID('D', 'a', 'r', 'k'):
- return FXDIB_BLEND_DARKEN;
- case FXBSTR_ID('L', 'i', 'g', 'h'):
- return FXDIB_BLEND_LIGHTEN;
- case FXBSTR_ID('C', 'o', 'l', 'o'):
- if (mode.GetLength() == 10) {
- return FXDIB_BLEND_COLORDODGE;
- }
- if (mode.GetLength() == 9) {
- return FXDIB_BLEND_COLORBURN;
- }
- return FXDIB_BLEND_COLOR;
- case FXBSTR_ID('H', 'a', 'r', 'd'):
- return FXDIB_BLEND_HARDLIGHT;
- case FXBSTR_ID('S', 'o', 'f', 't'):
- return FXDIB_BLEND_SOFTLIGHT;
- case FXBSTR_ID('D', 'i', 'f', 'f'):
- return FXDIB_BLEND_DIFFERENCE;
- case FXBSTR_ID('E', 'x', 'c', 'l'):
- return FXDIB_BLEND_EXCLUSION;
- case FXBSTR_ID('H', 'u', 'e', 0):
- return FXDIB_BLEND_HUE;
- case FXBSTR_ID('S', 'a', 't', 'u'):
- return FXDIB_BLEND_SATURATION;
- case FXBSTR_ID('L', 'u', 'm', 'i'):
- return FXDIB_BLEND_LUMINOSITY;
- }
- return FXDIB_BLEND_NORMAL;
-}
-void CPDF_GeneralStateData::SetBlendMode(FX_BSTR blend_mode)
-{
- if (blend_mode.GetLength() > 15) {
- return;
- }
- FXSYS_memcpy32(m_BlendMode, (FX_LPCBYTE)blend_mode, blend_mode.GetLength());
- m_BlendMode[blend_mode.GetLength()] = 0;
- m_BlendType = ::GetBlendType(blend_mode);
-}
-int RI_StringToId(const CFX_ByteString& ri)
-{
- FX_DWORD id = ri.GetID();
- if (id == FXBSTR_ID('A', 'b', 's', 'o')) {
- return 1;
- }
- if (id == FXBSTR_ID('S', 'a', 't', 'u')) {
- return 2;
- }
- if (id == FXBSTR_ID('P', 'e', 'r', 'c')) {
- return 3;
- }
- return 0;
-}
-void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri)
-{
- GetModify()->m_RenderIntent = RI_StringToId(ri);
-}
-CPDF_AllStates::CPDF_AllStates()
-{
- m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0;
- m_TextLeading = 0;
- m_TextRise = 0;
- m_TextHorzScale = 1.0f;
-}
-CPDF_AllStates::~CPDF_AllStates()
-{
-}
-void CPDF_AllStates::Copy(const CPDF_AllStates& src)
-{
- CopyStates(src);
- m_TextMatrix.Copy(src.m_TextMatrix);
- m_ParentMatrix.Copy(src.m_ParentMatrix);
- m_CTM.Copy(src.m_CTM);
- m_TextX = src.m_TextX;
- m_TextY = src.m_TextY;
- m_TextLineX = src.m_TextLineX;
- m_TextLineY = src.m_TextLineY;
- m_TextLeading = src.m_TextLeading;
- m_TextRise = src.m_TextRise;
- m_TextHorzScale = src.m_TextHorzScale;
-}
-void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale)
-{
- CFX_GraphStateData* pData = m_GraphState.GetModify();
- pData->m_DashPhase = FXSYS_Mul(phase, scale);
- pData->SetDashCount(pArray->GetCount());
- for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
- pData->m_DashArray[i] = FXSYS_Mul(pArray->GetNumber(i), scale);
- }
-}
-void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser)
-{
- CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify();
- FX_POSITION pos = pGS->GetStartPos();
- while (pos) {
- CFX_ByteString key_str;
- CPDF_Object* pObject = pGS->GetNextElement(pos, key_str)->GetDirect();
- if (pObject == NULL) {
- continue;
- }
- FX_DWORD key = key_str.GetID();
- switch (key) {
- case FXBSTR_ID('L', 'W', 0, 0):
- m_GraphState.GetModify()->m_LineWidth = pObject->GetNumber();
- break;
- case FXBSTR_ID('L', 'C', 0, 0):
- m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)pObject->GetInteger();
- break;
- case FXBSTR_ID('L', 'J', 0, 0):
- m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)pObject->GetInteger();
- break;
- case FXBSTR_ID('M', 'L', 0, 0):
- m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber();
- break;
- case FXBSTR_ID('D', 0, 0, 0): {
- if (pObject->GetType() != PDFOBJ_ARRAY) {
- break;
- }
- CPDF_Array* pDash = (CPDF_Array*)pObject;
- CPDF_Array* pArray = pDash->GetArray(0);
- if (pArray == NULL) {
- break;
- }
- SetLineDash(pArray, pDash->GetNumber(1), 1.0f);
- break;
- }
- case FXBSTR_ID('R', 'I', 0, 0):
- m_GeneralState.SetRenderIntent(pObject->GetString());
- break;
- case FXBSTR_ID('F', 'o', 'n', 't'): {
- if (pObject->GetType() != PDFOBJ_ARRAY) {
- break;
- }
- CPDF_Array* pFont = (CPDF_Array*)pObject;
- m_TextState.GetModify()->m_FontSize = pFont->GetNumber(1);
- m_TextState.SetFont(pParser->FindFont(pFont->GetString(0)));
- break;
- }
- case FXBSTR_ID('T', 'R', 0, 0):
- if (pGS->KeyExist(FX_BSTRC("TR2"))) {
- continue;
- }
- case FXBSTR_ID('T', 'R', '2', 0):
- if (pObject && pObject->GetType() != PDFOBJ_NAME) {
- pGeneralState->m_pTR = pObject;
- } else {
- pGeneralState->m_pTR = NULL;
- }
- break;
- case FXBSTR_ID('B', 'M', 0, 0): {
- CFX_ByteString mode;
- if (pObject->GetType() == PDFOBJ_ARRAY) {
- mode = ((CPDF_Array*)pObject)->GetString(0);
- } else {
- mode = pObject->GetString();
- }
- pGeneralState->SetBlendMode(mode);
- if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) {
- pParser->m_pObjectList->m_bBackgroundAlphaNeeded = TRUE;
- }
- break;
- }
- case FXBSTR_ID('S', 'M', 'a', 's'):
- if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) {
- pGeneralState->m_pSoftMask = pObject;
- FXSYS_memcpy32(pGeneralState->m_SMaskMatrix, &pParser->m_pCurStates->m_CTM, sizeof(CPDF_Matrix));
- } else {
- pGeneralState->m_pSoftMask = NULL;
- }
- break;
- case FXBSTR_ID('C', 'A', 0, 0):
- pGeneralState->m_StrokeAlpha = PDF_ClipFloat(pObject->GetNumber());
- break;
- case FXBSTR_ID('c', 'a', 0, 0):
- pGeneralState->m_FillAlpha = PDF_ClipFloat(pObject->GetNumber());
- break;
- case FXBSTR_ID('O', 'P', 0, 0):
- pGeneralState->m_StrokeOP = pObject->GetInteger();
- if (!pGS->KeyExist(FX_BSTRC("op"))) {
- pGeneralState->m_FillOP = pObject->GetInteger();
- }
- break;
- case FXBSTR_ID('o', 'p', 0, 0):
- pGeneralState->m_FillOP = pObject->GetInteger();
- break;
- case FXBSTR_ID('O', 'P', 'M', 0):
- pGeneralState->m_OPMode = pObject->GetInteger();
- break;
- case FXBSTR_ID('B', 'G', 0, 0):
- if (pGS->KeyExist(FX_BSTRC("BG2"))) {
- continue;
- }
- case FXBSTR_ID('B', 'G', '2', 0):
- pGeneralState->m_pBG = pObject;
- break;
- case FXBSTR_ID('U', 'C', 'R', 0):
- if (pGS->KeyExist(FX_BSTRC("UCR2"))) {
- continue;
- }
- case FXBSTR_ID('U', 'C', 'R', '2'):
- pGeneralState->m_pUCR = pObject;
- break;
- case FXBSTR_ID('H', 'T', 0, 0):
- pGeneralState->m_pHT = pObject;
- break;
- case FXBSTR_ID('F', 'L', 0, 0):
- pGeneralState->m_Flatness = pObject->GetNumber();
- break;
- case FXBSTR_ID('S', 'M', 0, 0):
- pGeneralState->m_Smoothness = pObject->GetNumber();
- break;
- case FXBSTR_ID('S', 'A', 0, 0):
- pGeneralState->m_StrokeAdjust = pObject->GetInteger();
- break;
- case FXBSTR_ID('A', 'I', 'S', 0):
- pGeneralState->m_AlphaSource = pObject->GetInteger();
- break;
- case FXBSTR_ID('T', 'K', 0, 0):
- pGeneralState->m_TextKnockout = pObject->GetInteger();
- break;
- }
- }
- pGeneralState->m_Matrix = m_CTM;
-}
-CPDF_ContentMarkItem::CPDF_ContentMarkItem()
-{
- m_ParamType = None;
-}
-CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src)
-{
- m_MarkName = src.m_MarkName;
- m_ParamType = src.m_ParamType;
- if (m_ParamType == DirectDict) {
- m_pParam = ((CPDF_Dictionary*)src.m_pParam)->Clone();
- } else {
- m_pParam = src.m_pParam;
- }
-}
-CPDF_ContentMarkItem::~CPDF_ContentMarkItem()
-{
- if (m_ParamType == DirectDict) {
- ((CPDF_Dictionary*)m_pParam)->Release();
- }
-}
-FX_BOOL CPDF_ContentMarkItem::HasMCID() const
-{
- if (m_pParam && (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) {
- return ((CPDF_Dictionary *)m_pParam)->KeyExist(FX_BSTRC("MCID"));
- }
- return FALSE;
-}
-CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src)
-{
- for (int i = 0; i < src.m_Marks.GetSize(); i ++) {
- m_Marks.Add(src.m_Marks[i]);
- }
-}
-int CPDF_ContentMarkData::GetMCID() const
-{
- CPDF_ContentMarkItem::ParamType type = CPDF_ContentMarkItem::None;
- for (int i = 0; i < m_Marks.GetSize(); i ++) {
- type = m_Marks[i].GetParamType();
- if (type == CPDF_ContentMarkItem::PropertiesDict || type == CPDF_ContentMarkItem::DirectDict) {
- CPDF_Dictionary *pDict = (CPDF_Dictionary *)m_Marks[i].GetParam();
- if (pDict->KeyExist(FX_BSTRC("MCID"))) {
- return pDict->GetInteger(FX_BSTRC("MCID"));
- }
- }
- }
- return -1;
-}
-void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name, CPDF_Dictionary* pDict, FX_BOOL bDirect)
-{
- CPDF_ContentMarkItem& item = m_Marks.Add();
- item.SetName(name);
- if (pDict == NULL) {
- return;
- }
- item.SetParam(bDirect ? CPDF_ContentMarkItem::DirectDict : CPDF_ContentMarkItem::PropertiesDict,
- bDirect ? pDict->Clone() : pDict);
-}
-void CPDF_ContentMarkData::DeleteLastMark()
-{
- int size = m_Marks.GetSize();
- if (size == 0) {
- return;
- }
- m_Marks.RemoveAt(size - 1);
-}
-FX_BOOL CPDF_ContentMark::HasMark(FX_BSTR mark) const
-{
- if (m_pObject == NULL) {
- return FALSE;
- }
- for (int i = 0; i < m_pObject->CountItems(); i ++) {
- CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
- if (item.GetName() == mark) {
- return TRUE;
- }
- }
- return FALSE;
-}
-FX_BOOL CPDF_ContentMark::LookupMark(FX_BSTR mark, CPDF_Dictionary*& pDict) const
-{
- if (m_pObject == NULL) {
- return FALSE;
- }
- for (int i = 0; i < m_pObject->CountItems(); i ++) {
- CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
- if (item.GetName() == mark) {
- pDict = NULL;
- if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict ||
- item.GetParamType() == CPDF_ContentMarkItem::DirectDict) {
- pDict = (CPDF_Dictionary*)item.GetParam();
- }
- return TRUE;
- }
- }
- return FALSE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_pageobj.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fpdfapi/fpdf_render.h" +#include "pageint.h" +#include "../fpdf_render/render_int.h" +void CPDF_GraphicStates::DefaultStates() +{ + m_ColorState.New()->Default(); +} +void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src) +{ + m_ClipPath = src.m_ClipPath; + m_GraphState = src.m_GraphState; + m_ColorState = src.m_ColorState; + m_TextState = src.m_TextState; + m_GeneralState = src.m_GeneralState; +} +CPDF_ClipPathData::CPDF_ClipPathData() +{ + m_PathCount = 0; + m_pPathList = NULL; + m_pTypeList = NULL; + m_TextCount = 0; + m_pTextList = NULL; +} +CPDF_ClipPathData::~CPDF_ClipPathData() +{ + int i; + if (m_pPathList) { + FX_DELETE_VECTOR(m_pPathList, CPDF_Path, m_PathCount); + } + if (m_pTypeList) { + FX_Free(m_pTypeList); + } + for (i = m_TextCount - 1; i > -1; i --) + if (m_pTextList[i]) { + delete m_pTextList[i]; + } + if (m_pTextList) { + FX_Free(m_pTextList); + } +} +CPDF_ClipPathData::CPDF_ClipPathData(const CPDF_ClipPathData& src) +{ + m_pPathList = NULL; + m_pPathList = NULL; + m_pTextList = NULL; + m_PathCount = src.m_PathCount; + if (m_PathCount) { + int alloc_size = m_PathCount; + if (alloc_size % 8) { + alloc_size += 8 - (alloc_size % 8); + } + FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size); + for (int i = 0; i < m_PathCount; i ++) { + m_pPathList[i] = src.m_pPathList[i]; + } + m_pTypeList = FX_Alloc(FX_BYTE, alloc_size); + FXSYS_memcpy32(m_pTypeList, src.m_pTypeList, m_PathCount); + } else { + m_pPathList = NULL; + m_pTypeList = NULL; + } + m_TextCount = src.m_TextCount; + if (m_TextCount) { + m_pTextList = FX_Alloc(CPDF_TextObject*, m_TextCount); + FXSYS_memset32(m_pTextList, 0, sizeof(CPDF_TextObject*) * m_TextCount); + for (int i = 0; i < m_TextCount; i ++) { + if (src.m_pTextList[i]) { + m_pTextList[i] = FX_NEW CPDF_TextObject; + m_pTextList[i]->Copy(src.m_pTextList[i]); + } else { + m_pTextList[i] = NULL; + } + } + } else { + m_pTextList = NULL; + } +} +void CPDF_ClipPathData::SetCount(int path_count, int text_count) +{ + ASSERT(m_TextCount == 0 && m_PathCount == 0); + if (path_count) { + m_PathCount = path_count; + int alloc_size = (path_count + 7) / 8 * 8; + FX_NEW_VECTOR(m_pPathList, CPDF_Path, alloc_size); + m_pTypeList = FX_Alloc(FX_BYTE, alloc_size); + } + if (text_count) { + m_TextCount = text_count; + m_pTextList = FX_Alloc(CPDF_TextObject*, text_count); + FXSYS_memset32(m_pTextList, 0, sizeof(void*) * text_count); + } +} +CPDF_Rect CPDF_ClipPath::GetClipBox() const +{ + CPDF_Rect rect; + FX_BOOL bStarted = FALSE; + int count = GetPathCount(); + if (count) { + rect = GetPath(0).GetBoundingBox(); + for (int i = 1; i < count; i ++) { + CPDF_Rect path_rect = GetPath(i).GetBoundingBox(); + rect.Intersect(path_rect); + } + bStarted = TRUE; + } + count = GetTextCount(); + if (count) { + CPDF_Rect layer_rect; + FX_BOOL bLayerStarted = FALSE; + for (int i = 0; i < count; i ++) { + CPDF_TextObject* pTextObj = GetText(i); + if (pTextObj == NULL) { + if (!bStarted) { + rect = layer_rect; + bStarted = TRUE; + } else { + rect.Intersect(layer_rect); + } + bLayerStarted = FALSE; + } else { + if (!bLayerStarted) { + layer_rect = pTextObj->GetBBox(NULL); + bLayerStarted = TRUE; + } else { + layer_rect.Union(pTextObj->GetBBox(NULL)); + } + } + } + } + return rect; +} +void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) +{ + CPDF_ClipPathData* pData = GetModify(); + if (pData->m_PathCount && bAutoMerge) { + CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1]; + if (old_path.IsRect()) { + CPDF_Rect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), + old_path.GetPointX(2), old_path.GetPointY(2)); + CPDF_Rect new_rect = path.GetBoundingBox(); + if (old_rect.Contains(new_rect)) { + pData->m_PathCount --; + pData->m_pPathList[pData->m_PathCount].SetNull(); + } + } + } + if (pData->m_PathCount % 8 == 0) { + CPDF_Path* pNewPath; + FX_NEW_VECTOR(pNewPath, CPDF_Path, pData->m_PathCount + 8); + for (int i = 0; i < pData->m_PathCount; i ++) { + pNewPath[i] = pData->m_pPathList[i]; + } + if (pData->m_pPathList) { + FX_DELETE_VECTOR(pData->m_pPathList, CPDF_Path, pData->m_PathCount); + } + FX_BYTE* pNewType = FX_Alloc(FX_BYTE, pData->m_PathCount + 8); + FXSYS_memcpy32(pNewType, pData->m_pTypeList, pData->m_PathCount); + if (pData->m_pTypeList) { + FX_Free(pData->m_pTypeList); + } + pData->m_pPathList = pNewPath; + pData->m_pTypeList = pNewType; + } + pData->m_pPathList[pData->m_PathCount] = path; + pData->m_pTypeList[pData->m_PathCount] = (FX_BYTE)type; + pData->m_PathCount ++; +} +void CPDF_ClipPath::DeletePath(int index) +{ + CPDF_ClipPathData* pData = GetModify(); + if (index >= pData->m_PathCount) { + return; + } + pData->m_pPathList[index].SetNull(); + for (int i = index; i < pData->m_PathCount - 1; i ++) { + pData->m_pPathList[i] = pData->m_pPathList[i + 1]; + } + pData->m_pPathList[pData->m_PathCount - 1].SetNull(); + FXSYS_memmove32(pData->m_pTypeList + index, pData->m_pTypeList + index + 1, pData->m_PathCount - index - 1); + pData->m_PathCount --; +} +#define FPDF_CLIPPATH_MAX_TEXTS 1024 +void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count) +{ + CPDF_ClipPathData* pData = GetModify(); + if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) { + for (int i = 0; i < count; i ++) { + pTexts[i]->Release(); + } + return; + } + CPDF_TextObject** pNewList = FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1); + if (pData->m_pTextList) { + FXSYS_memcpy32(pNewList, pData->m_pTextList, pData->m_TextCount * sizeof(CPDF_TextObject*)); + FX_Free(pData->m_pTextList); + } + pData->m_pTextList = pNewList; + for (int i = 0; i < count; i ++) { + pData->m_pTextList[pData->m_TextCount + i] = pTexts[i]; + } + pData->m_pTextList[pData->m_TextCount + count] = NULL; + pData->m_TextCount += count + 1; +} +void CPDF_ClipPath::Transform(const CPDF_Matrix& matrix) +{ + CPDF_ClipPathData* pData = GetModify(); + int i; + for (i = 0; i < pData->m_PathCount; i ++) { + pData->m_pPathList[i].Transform(&matrix); + } + for (i = 0; i < pData->m_TextCount; i ++) + if (pData->m_pTextList[i]) { + pData->m_pTextList[i]->Transform(matrix); + } +} +CPDF_ColorStateData::CPDF_ColorStateData(const CPDF_ColorStateData& src) +{ + m_FillColor.Copy(&src.m_FillColor); + m_FillRGB = src.m_FillRGB; + m_StrokeColor.Copy(&src.m_StrokeColor); + m_StrokeRGB = src.m_StrokeRGB; +} +void CPDF_ColorStateData::Default() +{ + m_FillRGB = m_StrokeRGB = 0; + m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); + m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); +} +void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) +{ + CPDF_ColorStateData* pData = GetModify(); + SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues); +} +void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) +{ + CPDF_ColorStateData* pData = GetModify(); + SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues); +} +void CPDF_ColorState::SetColor(CPDF_Color& color, FX_DWORD& rgb, CPDF_ColorSpace* pCS, FX_FLOAT* pValue, int nValues) +{ + if (pCS) { + color.SetColorSpace(pCS); + } else if (color.IsNull()) { + color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); + } + if (color.m_pCS->CountComponents() > nValues) { + return; + } + color.SetValue(pValue); + int R, G, B; + rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; +} +void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues) +{ + CPDF_ColorStateData* pData = GetModify(); + pData->m_FillColor.SetValue(pPattern, pValue, nValues); + int R, G, B; + FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B); + if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) { + pData->m_FillRGB = 0x00BFBFBF; + return; + } + pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; +} +void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue, int nValues) +{ + CPDF_ColorStateData* pData = GetModify(); + pData->m_StrokeColor.SetValue(pPattern, pValue, nValues); + int R, G, B; + FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B); + if (pPattern->m_PatternType == 1 && ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) { + pData->m_StrokeRGB = 0x00BFBFBF; + return; + } + pData->m_StrokeRGB = pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD) - 1; +} +CPDF_TextStateData::CPDF_TextStateData() +{ + m_pFont = NULL; + m_FontSize = 1.0f; + m_WordSpace = 0; + m_CharSpace = 0; + m_TextMode = 0; + m_Matrix[0] = m_Matrix[3] = 1.0f; + m_Matrix[1] = m_Matrix[2] = 0; + m_CTM[0] = m_CTM[3] = 1.0f; + m_CTM[1] = m_CTM[2] = 0; +} +CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src) +{ + FXSYS_memcpy32(this, &src, sizeof(CPDF_TextStateData)); + if (m_pFont && m_pFont->m_pDocument) { + m_pFont = m_pFont->m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE); + } +} +CPDF_TextStateData::~CPDF_TextStateData() +{ + CPDF_Font* pFont = m_pFont; + if (pFont && pFont->m_pDocument) { + pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict()); + } +} +void CPDF_TextState::SetFont(CPDF_Font* pFont) +{ + CPDF_Font*& pStateFont = GetModify()->m_pFont; + CPDF_DocPageData* pDocPageData = NULL; + if (pStateFont && pStateFont->m_pDocument) { + pDocPageData = pStateFont->m_pDocument->GetPageData(); + pDocPageData->ReleaseFont(pStateFont->GetFontDict()); + } + pStateFont = pFont; +} +FX_FLOAT CPDF_TextState::GetFontSizeV() const +{ + FX_FLOAT* pMatrix = GetMatrix(); + FX_FLOAT unit = FXSYS_sqrt2(pMatrix[1], pMatrix[3]); + FX_FLOAT size = FXSYS_Mul(unit, GetFontSize()); + return (FX_FLOAT)FXSYS_fabs(size); +} +FX_FLOAT CPDF_TextState::GetFontSizeH() const +{ + FX_FLOAT* pMatrix = GetMatrix(); + FX_FLOAT unit = FXSYS_sqrt2(pMatrix[0], pMatrix[2]); + FX_FLOAT size = FXSYS_Mul(unit, GetFontSize()); + return (FX_FLOAT)FXSYS_fabs(size); +} +FX_FLOAT CPDF_TextState::GetBaselineAngle() const +{ + FX_FLOAT* m_Matrix = GetMatrix(); + return FXSYS_atan2(m_Matrix[2], m_Matrix[0]); +} +FX_FLOAT CPDF_TextState::GetShearAngle() const +{ + FX_FLOAT* m_Matrix = GetMatrix(); + FX_FLOAT shear_angle = FXSYS_atan2(m_Matrix[1], m_Matrix[3]); + return GetBaselineAngle() + shear_angle; +} +CPDF_GeneralStateData::CPDF_GeneralStateData() +{ + FXSYS_memset32(this, 0, sizeof(CPDF_GeneralStateData)); + FXSYS_strcpy((FX_LPSTR)m_BlendMode, (FX_LPCSTR)"Normal"); + m_StrokeAlpha = 1.0f; + m_FillAlpha = 1.0f; + m_Flatness = 1.0f; + m_Matrix.SetIdentity(); +} +CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src) +{ + FXSYS_memcpy32(this, &src, sizeof(CPDF_GeneralStateData)); + if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) { + CPDF_DocRenderData* pDocCache = src.m_pTransferFunc->m_pPDFDoc->GetRenderData(); + if (!pDocCache) { + return; + } + m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR); + } +} +CPDF_GeneralStateData::~CPDF_GeneralStateData() +{ + if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) { + CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData(); + if (!pDocCache) { + return; + } + pDocCache->ReleaseTransferFunc(m_pTR); + } +} +static int GetBlendType(FX_BSTR mode) +{ + switch (mode.GetID()) { + case FXBSTR_ID('N', 'o', 'r', 'm'): + case FXBSTR_ID('C', 'o', 'm', 'p'): + return FXDIB_BLEND_NORMAL; + case FXBSTR_ID('M', 'u', 'l', 't'): + return FXDIB_BLEND_MULTIPLY; + case FXBSTR_ID('S', 'c', 'r', 'e'): + return FXDIB_BLEND_SCREEN; + case FXBSTR_ID('O', 'v', 'e', 'r'): + return FXDIB_BLEND_OVERLAY; + case FXBSTR_ID('D', 'a', 'r', 'k'): + return FXDIB_BLEND_DARKEN; + case FXBSTR_ID('L', 'i', 'g', 'h'): + return FXDIB_BLEND_LIGHTEN; + case FXBSTR_ID('C', 'o', 'l', 'o'): + if (mode.GetLength() == 10) { + return FXDIB_BLEND_COLORDODGE; + } + if (mode.GetLength() == 9) { + return FXDIB_BLEND_COLORBURN; + } + return FXDIB_BLEND_COLOR; + case FXBSTR_ID('H', 'a', 'r', 'd'): + return FXDIB_BLEND_HARDLIGHT; + case FXBSTR_ID('S', 'o', 'f', 't'): + return FXDIB_BLEND_SOFTLIGHT; + case FXBSTR_ID('D', 'i', 'f', 'f'): + return FXDIB_BLEND_DIFFERENCE; + case FXBSTR_ID('E', 'x', 'c', 'l'): + return FXDIB_BLEND_EXCLUSION; + case FXBSTR_ID('H', 'u', 'e', 0): + return FXDIB_BLEND_HUE; + case FXBSTR_ID('S', 'a', 't', 'u'): + return FXDIB_BLEND_SATURATION; + case FXBSTR_ID('L', 'u', 'm', 'i'): + return FXDIB_BLEND_LUMINOSITY; + } + return FXDIB_BLEND_NORMAL; +} +void CPDF_GeneralStateData::SetBlendMode(FX_BSTR blend_mode) +{ + if (blend_mode.GetLength() > 15) { + return; + } + FXSYS_memcpy32(m_BlendMode, (FX_LPCBYTE)blend_mode, blend_mode.GetLength()); + m_BlendMode[blend_mode.GetLength()] = 0; + m_BlendType = ::GetBlendType(blend_mode); +} +int RI_StringToId(const CFX_ByteString& ri) +{ + FX_DWORD id = ri.GetID(); + if (id == FXBSTR_ID('A', 'b', 's', 'o')) { + return 1; + } + if (id == FXBSTR_ID('S', 'a', 't', 'u')) { + return 2; + } + if (id == FXBSTR_ID('P', 'e', 'r', 'c')) { + return 3; + } + return 0; +} +void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) +{ + GetModify()->m_RenderIntent = RI_StringToId(ri); +} +CPDF_AllStates::CPDF_AllStates() +{ + m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0; + m_TextLeading = 0; + m_TextRise = 0; + m_TextHorzScale = 1.0f; +} +CPDF_AllStates::~CPDF_AllStates() +{ +} +void CPDF_AllStates::Copy(const CPDF_AllStates& src) +{ + CopyStates(src); + m_TextMatrix.Copy(src.m_TextMatrix); + m_ParentMatrix.Copy(src.m_ParentMatrix); + m_CTM.Copy(src.m_CTM); + m_TextX = src.m_TextX; + m_TextY = src.m_TextY; + m_TextLineX = src.m_TextLineX; + m_TextLineY = src.m_TextLineY; + m_TextLeading = src.m_TextLeading; + m_TextRise = src.m_TextRise; + m_TextHorzScale = src.m_TextHorzScale; +} +void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, FX_FLOAT phase, FX_FLOAT scale) +{ + CFX_GraphStateData* pData = m_GraphState.GetModify(); + pData->m_DashPhase = FXSYS_Mul(phase, scale); + pData->SetDashCount(pArray->GetCount()); + for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { + pData->m_DashArray[i] = FXSYS_Mul(pArray->GetNumber(i), scale); + } +} +void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser) +{ + CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify(); + FX_POSITION pos = pGS->GetStartPos(); + while (pos) { + CFX_ByteString key_str; + CPDF_Object* pObject = pGS->GetNextElement(pos, key_str)->GetDirect(); + if (pObject == NULL) { + continue; + } + FX_DWORD key = key_str.GetID(); + switch (key) { + case FXBSTR_ID('L', 'W', 0, 0): + m_GraphState.GetModify()->m_LineWidth = pObject->GetNumber(); + break; + case FXBSTR_ID('L', 'C', 0, 0): + m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)pObject->GetInteger(); + break; + case FXBSTR_ID('L', 'J', 0, 0): + m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)pObject->GetInteger(); + break; + case FXBSTR_ID('M', 'L', 0, 0): + m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber(); + break; + case FXBSTR_ID('D', 0, 0, 0): { + if (pObject->GetType() != PDFOBJ_ARRAY) { + break; + } + CPDF_Array* pDash = (CPDF_Array*)pObject; + CPDF_Array* pArray = pDash->GetArray(0); + if (pArray == NULL) { + break; + } + SetLineDash(pArray, pDash->GetNumber(1), 1.0f); + break; + } + case FXBSTR_ID('R', 'I', 0, 0): + m_GeneralState.SetRenderIntent(pObject->GetString()); + break; + case FXBSTR_ID('F', 'o', 'n', 't'): { + if (pObject->GetType() != PDFOBJ_ARRAY) { + break; + } + CPDF_Array* pFont = (CPDF_Array*)pObject; + m_TextState.GetModify()->m_FontSize = pFont->GetNumber(1); + m_TextState.SetFont(pParser->FindFont(pFont->GetString(0))); + break; + } + case FXBSTR_ID('T', 'R', 0, 0): + if (pGS->KeyExist(FX_BSTRC("TR2"))) { + continue; + } + case FXBSTR_ID('T', 'R', '2', 0): + if (pObject && pObject->GetType() != PDFOBJ_NAME) { + pGeneralState->m_pTR = pObject; + } else { + pGeneralState->m_pTR = NULL; + } + break; + case FXBSTR_ID('B', 'M', 0, 0): { + CFX_ByteString mode; + if (pObject->GetType() == PDFOBJ_ARRAY) { + mode = ((CPDF_Array*)pObject)->GetString(0); + } else { + mode = pObject->GetString(); + } + pGeneralState->SetBlendMode(mode); + if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) { + pParser->m_pObjectList->m_bBackgroundAlphaNeeded = TRUE; + } + break; + } + case FXBSTR_ID('S', 'M', 'a', 's'): + if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) { + pGeneralState->m_pSoftMask = pObject; + FXSYS_memcpy32(pGeneralState->m_SMaskMatrix, &pParser->m_pCurStates->m_CTM, sizeof(CPDF_Matrix)); + } else { + pGeneralState->m_pSoftMask = NULL; + } + break; + case FXBSTR_ID('C', 'A', 0, 0): + pGeneralState->m_StrokeAlpha = PDF_ClipFloat(pObject->GetNumber()); + break; + case FXBSTR_ID('c', 'a', 0, 0): + pGeneralState->m_FillAlpha = PDF_ClipFloat(pObject->GetNumber()); + break; + case FXBSTR_ID('O', 'P', 0, 0): + pGeneralState->m_StrokeOP = pObject->GetInteger(); + if (!pGS->KeyExist(FX_BSTRC("op"))) { + pGeneralState->m_FillOP = pObject->GetInteger(); + } + break; + case FXBSTR_ID('o', 'p', 0, 0): + pGeneralState->m_FillOP = pObject->GetInteger(); + break; + case FXBSTR_ID('O', 'P', 'M', 0): + pGeneralState->m_OPMode = pObject->GetInteger(); + break; + case FXBSTR_ID('B', 'G', 0, 0): + if (pGS->KeyExist(FX_BSTRC("BG2"))) { + continue; + } + case FXBSTR_ID('B', 'G', '2', 0): + pGeneralState->m_pBG = pObject; + break; + case FXBSTR_ID('U', 'C', 'R', 0): + if (pGS->KeyExist(FX_BSTRC("UCR2"))) { + continue; + } + case FXBSTR_ID('U', 'C', 'R', '2'): + pGeneralState->m_pUCR = pObject; + break; + case FXBSTR_ID('H', 'T', 0, 0): + pGeneralState->m_pHT = pObject; + break; + case FXBSTR_ID('F', 'L', 0, 0): + pGeneralState->m_Flatness = pObject->GetNumber(); + break; + case FXBSTR_ID('S', 'M', 0, 0): + pGeneralState->m_Smoothness = pObject->GetNumber(); + break; + case FXBSTR_ID('S', 'A', 0, 0): + pGeneralState->m_StrokeAdjust = pObject->GetInteger(); + break; + case FXBSTR_ID('A', 'I', 'S', 0): + pGeneralState->m_AlphaSource = pObject->GetInteger(); + break; + case FXBSTR_ID('T', 'K', 0, 0): + pGeneralState->m_TextKnockout = pObject->GetInteger(); + break; + } + } + pGeneralState->m_Matrix = m_CTM; +} +CPDF_ContentMarkItem::CPDF_ContentMarkItem() +{ + m_ParamType = None; +} +CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src) +{ + m_MarkName = src.m_MarkName; + m_ParamType = src.m_ParamType; + if (m_ParamType == DirectDict) { + m_pParam = ((CPDF_Dictionary*)src.m_pParam)->Clone(); + } else { + m_pParam = src.m_pParam; + } +} +CPDF_ContentMarkItem::~CPDF_ContentMarkItem() +{ + if (m_ParamType == DirectDict) { + ((CPDF_Dictionary*)m_pParam)->Release(); + } +} +FX_BOOL CPDF_ContentMarkItem::HasMCID() const +{ + if (m_pParam && (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) { + return ((CPDF_Dictionary *)m_pParam)->KeyExist(FX_BSTRC("MCID")); + } + return FALSE; +} +CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src) +{ + for (int i = 0; i < src.m_Marks.GetSize(); i ++) { + m_Marks.Add(src.m_Marks[i]); + } +} +int CPDF_ContentMarkData::GetMCID() const +{ + CPDF_ContentMarkItem::ParamType type = CPDF_ContentMarkItem::None; + for (int i = 0; i < m_Marks.GetSize(); i ++) { + type = m_Marks[i].GetParamType(); + if (type == CPDF_ContentMarkItem::PropertiesDict || type == CPDF_ContentMarkItem::DirectDict) { + CPDF_Dictionary *pDict = (CPDF_Dictionary *)m_Marks[i].GetParam(); + if (pDict->KeyExist(FX_BSTRC("MCID"))) { + return pDict->GetInteger(FX_BSTRC("MCID")); + } + } + } + return -1; +} +void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name, CPDF_Dictionary* pDict, FX_BOOL bDirect) +{ + CPDF_ContentMarkItem& item = m_Marks.Add(); + item.SetName(name); + if (pDict == NULL) { + return; + } + item.SetParam(bDirect ? CPDF_ContentMarkItem::DirectDict : CPDF_ContentMarkItem::PropertiesDict, + bDirect ? pDict->Clone() : pDict); +} +void CPDF_ContentMarkData::DeleteLastMark() +{ + int size = m_Marks.GetSize(); + if (size == 0) { + return; + } + m_Marks.RemoveAt(size - 1); +} +FX_BOOL CPDF_ContentMark::HasMark(FX_BSTR mark) const +{ + if (m_pObject == NULL) { + return FALSE; + } + for (int i = 0; i < m_pObject->CountItems(); i ++) { + CPDF_ContentMarkItem& item = m_pObject->GetItem(i); + if (item.GetName() == mark) { + return TRUE; + } + } + return FALSE; +} +FX_BOOL CPDF_ContentMark::LookupMark(FX_BSTR mark, CPDF_Dictionary*& pDict) const +{ + if (m_pObject == NULL) { + return FALSE; + } + for (int i = 0; i < m_pObject->CountItems(); i ++) { + CPDF_ContentMarkItem& item = m_pObject->GetItem(i); + if (item.GetName() == mark) { + pDict = NULL; + if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict || + item.GetParamType() == CPDF_ContentMarkItem::DirectDict) { + pDict = (CPDF_Dictionary*)item.GetParam(); + } + return TRUE; + } + } + return FALSE; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_image.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_image.cpp index ec351058ac..b1fbe01b90 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_image.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_image.cpp @@ -1,116 +1,116 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_pageobj.h"
-#include "pageint.h"
-CPDF_ImageObject::CPDF_ImageObject()
-{
- m_pImage = NULL;
- m_Type = PDFPAGE_IMAGE;
-}
-CPDF_ImageObject::~CPDF_ImageObject()
-{
- if (!m_pImage) {
- return;
- }
- if (m_pImage->IsInline() || (m_pImage->GetStream() && m_pImage->GetStream()->GetObjNum() == 0)) {
- delete m_pImage;
- } else {
- m_pImage->GetDocument()->GetPageData()->ReleaseImage(m_pImage->GetStream());
- }
-}
-void CPDF_ImageObject::CopyData(const CPDF_PageObject* pSrc)
-{
- const CPDF_ImageObject* pSrcObj = (const CPDF_ImageObject*)pSrc;
- if (m_pImage) {
- m_pImage->Release();
- }
- m_pImage = pSrcObj->m_pImage->Clone();
- m_Matrix = pSrcObj->m_Matrix;
-}
-void CPDF_ImageObject::Transform(const CFX_AffineMatrix& matrix)
-{
- m_Matrix.Concat(matrix);
- CalcBoundingBox();
-}
-void CPDF_ImageObject::CalcBoundingBox()
-{
- m_Left = m_Bottom = 0;
- m_Right = m_Top = 1.0f;
- m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
-}
-void CPDF_Image::Release()
-{
- if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0)) {
- delete this;
- }
-}
-CPDF_Image* CPDF_Image::Clone()
-{
- if (m_pStream->GetObjNum()) {
- return m_pDocument->GetPageData()->GetImage(m_pStream);
- }
- CPDF_Image* pImage = FX_NEW CPDF_Image(m_pDocument);
- pImage->LoadImageF((CPDF_Stream*)((CPDF_Object*)m_pStream)->Clone(), m_bInline);
- if (m_bInline) {
- CPDF_Dictionary *pInlineDict = (CPDF_Dictionary*)m_pInlineDict->Clone(TRUE);
- pImage->SetInlineDict(pInlineDict);
- }
- return pImage;
-}
-CPDF_Image::CPDF_Image(CPDF_Document* pDoc)
-{
- m_pDocument = pDoc;
- m_pStream = NULL;
- m_pOC = NULL;
- m_bInline = FALSE;
- m_pInlineDict = NULL;
- m_pDIBSource = NULL;
- m_pMask = NULL;
- m_MatteColor = 0;
-}
-CPDF_Image::~CPDF_Image()
-{
- if (m_bInline) {
- if (m_pStream) {
-#ifndef FOXIT_CHROME_BUILD
- CPDF_Dictionary* pDict = m_pStream->GetDict();
- if (pDict) {
- CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
- if (pCSObj && m_pDocument) {
- m_pDocument->RemoveColorSpaceFromPageData(pCSObj);
- }
- }
-#endif
- m_pStream->Release();
- }
- if (m_pInlineDict) {
- m_pInlineDict->Release();
- }
- }
-}
-FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline)
-{
- m_pStream = pStream;
- if (m_bInline && m_pInlineDict) {
- m_pInlineDict->Release();
- m_pInlineDict = NULL;
- }
- m_bInline = bInline;
- CPDF_Dictionary* pDict = pStream->GetDict();
- if (m_bInline) {
- m_pInlineDict = (CPDF_Dictionary*)pDict->Clone();
- }
- m_pOC = pDict->GetDict(FX_BSTRC("OC"));
- m_bIsMask = !pDict->KeyExist(FX_BSTRC("ColorSpace")) || pDict->GetInteger(FX_BSTRC("ImageMask"));
-#ifndef _FPDFAPI_MINI_
- m_bInterpolate = pDict->GetInteger(FX_BSTRC("Interpolate"));
-#endif
- m_Height = pDict->GetInteger(FX_BSTRC("Height"));
- m_Width = pDict->GetInteger(FX_BSTRC("Width"));
- return TRUE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_pageobj.h" +#include "pageint.h" +CPDF_ImageObject::CPDF_ImageObject() +{ + m_pImage = NULL; + m_Type = PDFPAGE_IMAGE; +} +CPDF_ImageObject::~CPDF_ImageObject() +{ + if (!m_pImage) { + return; + } + if (m_pImage->IsInline() || (m_pImage->GetStream() && m_pImage->GetStream()->GetObjNum() == 0)) { + delete m_pImage; + } else { + m_pImage->GetDocument()->GetPageData()->ReleaseImage(m_pImage->GetStream()); + } +} +void CPDF_ImageObject::CopyData(const CPDF_PageObject* pSrc) +{ + const CPDF_ImageObject* pSrcObj = (const CPDF_ImageObject*)pSrc; + if (m_pImage) { + m_pImage->Release(); + } + m_pImage = pSrcObj->m_pImage->Clone(); + m_Matrix = pSrcObj->m_Matrix; +} +void CPDF_ImageObject::Transform(const CFX_AffineMatrix& matrix) +{ + m_Matrix.Concat(matrix); + CalcBoundingBox(); +} +void CPDF_ImageObject::CalcBoundingBox() +{ + m_Left = m_Bottom = 0; + m_Right = m_Top = 1.0f; + m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); +} +void CPDF_Image::Release() +{ + if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0)) { + delete this; + } +} +CPDF_Image* CPDF_Image::Clone() +{ + if (m_pStream->GetObjNum()) { + return m_pDocument->GetPageData()->GetImage(m_pStream); + } + CPDF_Image* pImage = FX_NEW CPDF_Image(m_pDocument); + pImage->LoadImageF((CPDF_Stream*)((CPDF_Object*)m_pStream)->Clone(), m_bInline); + if (m_bInline) { + CPDF_Dictionary *pInlineDict = (CPDF_Dictionary*)m_pInlineDict->Clone(TRUE); + pImage->SetInlineDict(pInlineDict); + } + return pImage; +} +CPDF_Image::CPDF_Image(CPDF_Document* pDoc) +{ + m_pDocument = pDoc; + m_pStream = NULL; + m_pOC = NULL; + m_bInline = FALSE; + m_pInlineDict = NULL; + m_pDIBSource = NULL; + m_pMask = NULL; + m_MatteColor = 0; +} +CPDF_Image::~CPDF_Image() +{ + if (m_bInline) { + if (m_pStream) { +#ifndef FOXIT_CHROME_BUILD + CPDF_Dictionary* pDict = m_pStream->GetDict(); + if (pDict) { + CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj && m_pDocument) { + m_pDocument->RemoveColorSpaceFromPageData(pCSObj); + } + } +#endif + m_pStream->Release(); + } + if (m_pInlineDict) { + m_pInlineDict->Release(); + } + } +} +FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline) +{ + m_pStream = pStream; + if (m_bInline && m_pInlineDict) { + m_pInlineDict->Release(); + m_pInlineDict = NULL; + } + m_bInline = bInline; + CPDF_Dictionary* pDict = pStream->GetDict(); + if (m_bInline) { + m_pInlineDict = (CPDF_Dictionary*)pDict->Clone(); + } + m_pOC = pDict->GetDict(FX_BSTRC("OC")); + m_bIsMask = !pDict->KeyExist(FX_BSTRC("ColorSpace")) || pDict->GetInteger(FX_BSTRC("ImageMask")); +#ifndef _FPDFAPI_MINI_ + m_bInterpolate = pDict->GetInteger(FX_BSTRC("Interpolate")); +#endif + m_Height = pDict->GetInteger(FX_BSTRC("Height")); + m_Width = pDict->GetInteger(FX_BSTRC("Width")); + return TRUE; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 40f6d04212..ff670965ec 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -1,1681 +1,1681 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fpdfapi/fpdf_serial.h"
-#include "pageint.h"
-#define REQUIRE_PARAMS(count) if (m_ParamCount != count) { m_bAbort = TRUE; return; }
-CPDF_StreamContentParser::CPDF_StreamContentParser()
-{
- m_DefFontSize = 0;
- m_pCurStates = NULL;
- m_pLastTextObject = NULL;
- m_pPathPoints = NULL;
- m_PathClipType = 0;
- m_PathPointCount = m_PathAllocSize = 0;
- m_PathCurrentX = m_PathCurrentY = 0.0f;
- m_bResourceMissing = FALSE;
- m_bColored = FALSE;
- FXSYS_memset32(m_Type3Data, 0, sizeof(FX_FLOAT) * 6);
- m_ParamCount = 0;
- m_ParamStartPos = 0;
- m_bAbort = FALSE;
- m_pLastImageDict = NULL;
- m_pLastCloneImageDict = NULL;
- m_pLastImage = NULL;
- m_bReleaseLastDict = TRUE;
- m_pParentResources = NULL;
-#ifdef _FPDFAPI_MINI_
- m_pObjectState = NULL;
- m_pObjectStack = NULL;
- m_pWordBuf = NULL;
- m_pDictName = NULL;
- m_pStreamBuf = NULL;
- m_WordState = 0;
- m_ObjectSize = 0;
-#endif
-}
-FX_BOOL CPDF_StreamContentParser::Initialize()
-{
-#ifdef _FPDFAPI_MINI_
- m_pObjectState = FX_Alloc(FX_BOOL, _FPDF_MAX_OBJECT_STACK_SIZE_);
- FXSYS_memset32(m_pObjectState, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(FX_BOOL));
- m_pObjectStack = FX_Alloc(CPDF_Object*, _FPDF_MAX_OBJECT_STACK_SIZE_);
- FXSYS_memset32(m_pObjectStack, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(CPDF_Object*));
- m_pWordBuf = FX_Alloc(FX_BYTE, 256);
- FXSYS_memset32(m_pWordBuf, 0, 256 * sizeof(FX_BYTE));
- m_pDictName = FX_Alloc(FX_BYTE, 256);
- FXSYS_memset32(m_pDictName, 0, 256 * sizeof(FX_BYTE));
- m_pStreamBuf = FX_Alloc(FX_BYTE, STREAM_PARSE_BUFSIZE);
- FXSYS_memset32(m_pStreamBuf, 0, STREAM_PARSE_BUFSIZE * sizeof(FX_BYTE));
- m_StringBuf.EstimateSize(1024);
- m_ObjectSize = 0;
- m_ImageSrcBuf.EstimateSize(STREAM_PARSE_BUFSIZE);
-#endif
- return TRUE;
-}
-CPDF_StreamContentParser::~CPDF_StreamContentParser()
-{
- ClearAllParams();
- int i = 0;
- for (i = 0; i < m_StateStack.GetSize(); i ++) {
- delete (CPDF_AllStates*)m_StateStack[i];
- }
- if (m_pPathPoints) {
- FX_Free(m_pPathPoints);
- }
- if (m_pCurStates) {
- delete m_pCurStates;
- }
- if (m_pLastImageDict) {
- m_pLastImageDict->Release();
- }
- if (m_pLastCloneImageDict) {
- m_pLastCloneImageDict->Release();
- }
-#ifdef _FPDFAPI_MINI_
- for (i = 0; i < (int)m_ObjectSize; ++i) {
- if (!m_pObjectState[i]) {
- m_pObjectStack[i]->Release();
- }
- }
- FX_Free(m_pObjectStack);
- FX_Free(m_pObjectState);
- FX_Free(m_pStreamBuf);
- FX_Free(m_pWordBuf);
- FX_Free(m_pDictName);
-#endif
-}
-void CPDF_StreamContentParser::PrepareParse(CPDF_Document* pDocument,
- CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources, CFX_AffineMatrix* pmtContentToUser, CPDF_PageObjects* pObjList,
- CPDF_Dictionary* pResources, CPDF_Rect* pBBox, CPDF_ParseOptions* pOptions,
- CPDF_AllStates* pStates, int level)
-{
- for (int i = 0; i < 6; i ++) {
- m_Type3Data[i] = 0;
- }
- m_pDocument = pDocument;
- m_pPageResources = pPageResources;
- m_pParentResources = pParentResources;
- if (pmtContentToUser) {
- m_mtContentToUser = *pmtContentToUser;
- }
- if (pOptions) {
- m_Options = *pOptions;
- }
- m_pObjectList = pObjList;
- m_pResources = pResources;
- if (pResources == NULL) {
- m_pResources = m_pParentResources;
- }
- if (m_pResources == NULL) {
- m_pResources = pPageResources;
- }
- if (pBBox) {
- m_BBox = *pBBox;
- }
- m_Level = level;
- m_pCurStates = FX_NEW CPDF_AllStates;
- if (pStates) {
- m_pCurStates->Copy(*pStates);
- } else {
- m_pCurStates->m_GeneralState.New();
- m_pCurStates->m_GraphState.New();
- m_pCurStates->m_TextState.New();
- m_pCurStates->m_ColorState.New();
- }
-#ifdef _FPDFAPI_MINI_
- FXSYS_memset32(m_pObjectState, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(FX_BOOL));
-#endif
-}
-int CPDF_StreamContentParser::GetNextParamPos()
-{
- if (m_ParamCount == PARAM_BUF_SIZE) {
- m_ParamStartPos ++;
- if (m_ParamStartPos == PARAM_BUF_SIZE) {
- m_ParamStartPos = 0;
- }
- if (m_ParamBuf1[m_ParamStartPos].m_Type == 0) {
- m_ParamBuf1[m_ParamStartPos].m_pObject->Release();
- }
- return m_ParamStartPos;
- }
- int index = m_ParamStartPos + m_ParamCount;
- if (index >= PARAM_BUF_SIZE) {
- index -= PARAM_BUF_SIZE;
- }
- m_ParamCount ++;
- return index;
-}
-void CPDF_StreamContentParser::AddNameParam(FX_LPCSTR name, int len)
-{
- int index = GetNextParamPos();
- if (len > 32) {
- m_ParamBuf1[index].m_Type = 0;
- m_ParamBuf1[index].m_pObject = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(name, len)));
- } else {
- m_ParamBuf1[index].m_Type = PDFOBJ_NAME;
- if (FXSYS_memchr(name, '#', len) == NULL) {
- FXSYS_memcpy32(m_ParamBuf1[index].m_Name.m_Buffer, name, len);
- m_ParamBuf1[index].m_Name.m_Len = len;
- } else {
- CFX_ByteString str = PDF_NameDecode(CFX_ByteStringC(name, len));
- FXSYS_memcpy32(m_ParamBuf1[index].m_Name.m_Buffer, (FX_LPCSTR)str, str.GetLength());
- m_ParamBuf1[index].m_Name.m_Len = str.GetLength();
- }
- }
-}
-void CPDF_StreamContentParser::AddNumberParam(FX_LPCSTR str, int len)
-{
- int index = GetNextParamPos();
- m_ParamBuf1[index].m_Type = PDFOBJ_NUMBER;
- FX_atonum(CFX_ByteStringC(str, len), m_ParamBuf1[index].m_Number.m_bInteger,
- &m_ParamBuf1[index].m_Number.m_Integer);
-}
-void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj)
-{
- int index = GetNextParamPos();
- m_ParamBuf1[index].m_Type = 0;
- m_ParamBuf1[index].m_pObject = pObj;
-}
-void CPDF_StreamContentParser::ClearAllParams()
-{
- FX_DWORD index = m_ParamStartPos;
- for (FX_DWORD i = 0; i < m_ParamCount; i ++) {
- if (m_ParamBuf1[index].m_Type == 0) {
- m_ParamBuf1[index].m_pObject->Release();
- }
- index ++;
- if (index == PARAM_BUF_SIZE) {
- index = 0;
- }
- }
- m_ParamStartPos = 0;
- m_ParamCount = 0;
-}
-CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index)
-{
- if (index >= m_ParamCount) {
- return NULL;
- }
- int real_index = m_ParamStartPos + m_ParamCount - index - 1;
- if (real_index >= PARAM_BUF_SIZE) {
- real_index -= PARAM_BUF_SIZE;
- }
- _ContentParam& param = m_ParamBuf1[real_index];
- if (param.m_Type == PDFOBJ_NUMBER) {
- CPDF_Number* pNumber = CPDF_Number::Create(param.m_Number.m_bInteger, ¶m.m_Number.m_Integer);
- param.m_Type = 0;
- param.m_pObject = pNumber;
- return pNumber;
- }
- if (param.m_Type == PDFOBJ_NAME) {
- CPDF_Name* pName = CPDF_Name::Create(CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len));
- param.m_Type = 0;
- param.m_pObject = pName;
- return pName;
- }
- if (param.m_Type == 0) {
- return param.m_pObject;
- }
- ASSERT(FALSE);
- return NULL;
-}
-CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index)
-{
- if (index >= m_ParamCount) {
- return CFX_ByteString();
- }
- int real_index = m_ParamStartPos + m_ParamCount - index - 1;
- if (real_index >= PARAM_BUF_SIZE) {
- real_index -= PARAM_BUF_SIZE;
- }
- _ContentParam& param = m_ParamBuf1[real_index];
- if (param.m_Type == PDFOBJ_NAME) {
- return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len);
- }
- if (param.m_Type == 0) {
- return param.m_pObject->GetString();
- }
- return CFX_ByteString();
-}
-FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index)
-{
- if (index >= m_ParamCount) {
- return 0;
- }
- int real_index = m_ParamStartPos + m_ParamCount - index - 1;
- if (real_index >= PARAM_BUF_SIZE) {
- real_index -= PARAM_BUF_SIZE;
- }
- _ContentParam& param = m_ParamBuf1[real_index];
- if (param.m_Type == PDFOBJ_NUMBER) {
- return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer : param.m_Number.m_Float;
- }
- if (param.m_Type == 0) {
- return param.m_pObject->GetNumber();
- }
- return 0;
-}
-FX_FLOAT CPDF_StreamContentParser::GetNumber16(FX_DWORD index)
-{
- return GetNumber(index);
-}
-void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph)
-{
- pObj->m_GeneralState = m_pCurStates->m_GeneralState;
- pObj->m_ClipPath = m_pCurStates->m_ClipPath;
- pObj->m_ContentMark = m_CurContentMark;
- if (bColor) {
- pObj->m_ColorState = m_pCurStates->m_ColorState;
- }
- if (bGraph) {
- pObj->m_GraphState = m_pCurStates->m_GraphState;
- }
- if (bText) {
- pObj->m_TextState = m_pCurStates->m_TextState;
- }
-}
-const struct _OpCode {
- FX_DWORD m_OpId;
- void (CPDF_StreamContentParser::*m_OpHandler)();
-} g_OpCodes[] = {
- {FXBSTR_ID('"', 0, 0, 0), &CPDF_StreamContentParser::Handle_NextLineShowText_Space},
- {FXBSTR_ID('\'', 0, 0, 0), &CPDF_StreamContentParser::Handle_NextLineShowText},
- {FXBSTR_ID('B', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillStrokePath},
- {FXBSTR_ID('B', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillStrokePath},
- {FXBSTR_ID('B', 'D', 'C', 0), &CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary},
- {FXBSTR_ID('B', 'I', 0, 0), &CPDF_StreamContentParser::Handle_BeginImage},
- {FXBSTR_ID('B', 'M', 'C', 0), &CPDF_StreamContentParser::Handle_BeginMarkedContent},
- {FXBSTR_ID('B', 'T', 0, 0), &CPDF_StreamContentParser::Handle_BeginText},
- {FXBSTR_ID('B', 'X', 0, 0), &CPDF_StreamContentParser::Handle_BeginSectionUndefined},
- {FXBSTR_ID('C', 'S', 0, 0), &CPDF_StreamContentParser::Handle_SetColorSpace_Stroke},
- {FXBSTR_ID('D', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace_Dictionary},
- {FXBSTR_ID('D', 'o', 0, 0), &CPDF_StreamContentParser::Handle_ExecuteXObject},
- {FXBSTR_ID('E', 'I', 0, 0), &CPDF_StreamContentParser::Handle_EndImage},
- {FXBSTR_ID('E', 'M', 'C', 0), &CPDF_StreamContentParser::Handle_EndMarkedContent},
- {FXBSTR_ID('E', 'T', 0, 0), &CPDF_StreamContentParser::Handle_EndText},
- {FXBSTR_ID('E', 'X', 0, 0), &CPDF_StreamContentParser::Handle_EndSectionUndefined},
- {FXBSTR_ID('F', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPathOld},
- {FXBSTR_ID('G', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Stroke},
- {FXBSTR_ID('I', 'D', 0, 0), &CPDF_StreamContentParser::Handle_BeginImageData},
- {FXBSTR_ID('J', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineCap},
- {FXBSTR_ID('K', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke},
- {FXBSTR_ID('M', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetMiterLimit},
- {FXBSTR_ID('M', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace},
- {FXBSTR_ID('Q', 0, 0, 0), &CPDF_StreamContentParser::Handle_RestoreGraphState},
- {FXBSTR_ID('R', 'G', 0, 0), &CPDF_StreamContentParser::Handle_SetRGBColor_Stroke},
- {FXBSTR_ID('S', 0, 0, 0), &CPDF_StreamContentParser::Handle_StrokePath},
- {FXBSTR_ID('S', 'C', 0, 0), &CPDF_StreamContentParser::Handle_SetColor_Stroke},
- {FXBSTR_ID('S', 'C', 'N', 0), &CPDF_StreamContentParser::Handle_SetColorPS_Stroke},
- {FXBSTR_ID('T', '*', 0, 0), &CPDF_StreamContentParser::Handle_MoveToNextLine},
- {FXBSTR_ID('T', 'D', 0, 0), &CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading},
- {FXBSTR_ID('T', 'J', 0, 0), &CPDF_StreamContentParser::Handle_ShowText_Positioning},
- {FXBSTR_ID('T', 'L', 0, 0), &CPDF_StreamContentParser::Handle_SetTextLeading},
- {FXBSTR_ID('T', 'c', 0, 0), &CPDF_StreamContentParser::Handle_SetCharSpace},
- {FXBSTR_ID('T', 'd', 0, 0), &CPDF_StreamContentParser::Handle_MoveTextPoint},
- {FXBSTR_ID('T', 'f', 0, 0), &CPDF_StreamContentParser::Handle_SetFont},
- {FXBSTR_ID('T', 'j', 0, 0), &CPDF_StreamContentParser::Handle_ShowText},
- {FXBSTR_ID('T', 'm', 0, 0), &CPDF_StreamContentParser::Handle_SetTextMatrix},
- {FXBSTR_ID('T', 'r', 0, 0), &CPDF_StreamContentParser::Handle_SetTextRenderMode},
- {FXBSTR_ID('T', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetTextRise},
- {FXBSTR_ID('T', 'w', 0, 0), &CPDF_StreamContentParser::Handle_SetWordSpace},
- {FXBSTR_ID('T', 'z', 0, 0), &CPDF_StreamContentParser::Handle_SetHorzScale},
- {FXBSTR_ID('W', 0, 0, 0), &CPDF_StreamContentParser::Handle_Clip},
- {FXBSTR_ID('W', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOClip},
- {FXBSTR_ID('b', 0, 0, 0), &CPDF_StreamContentParser::Handle_CloseFillStrokePath},
- {FXBSTR_ID('b', '*', 0, 0), &CPDF_StreamContentParser::Handle_CloseEOFillStrokePath},
- {FXBSTR_ID('c', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_123},
- {FXBSTR_ID('c', 'm', 0, 0), &CPDF_StreamContentParser::Handle_ConcatMatrix},
- {FXBSTR_ID('c', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetColorSpace_Fill},
- {FXBSTR_ID('d', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetDash},
- {FXBSTR_ID('d', '0', 0, 0), &CPDF_StreamContentParser::Handle_SetCharWidth},
- {FXBSTR_ID('d', '1', 0, 0), &CPDF_StreamContentParser::Handle_SetCachedDevice},
- {FXBSTR_ID('f', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPath},
- {FXBSTR_ID('f', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillPath},
- {FXBSTR_ID('g', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Fill},
- {FXBSTR_ID('g', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetExtendGraphState},
- {FXBSTR_ID('h', 0, 0, 0), &CPDF_StreamContentParser::Handle_ClosePath},
- {FXBSTR_ID('i', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetFlat},
- {FXBSTR_ID('j', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineJoin},
- {FXBSTR_ID('k', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetCMYKColor_Fill},
- {FXBSTR_ID('l', 0, 0, 0), &CPDF_StreamContentParser::Handle_LineTo},
- {FXBSTR_ID('m', 0, 0, 0), &CPDF_StreamContentParser::Handle_MoveTo},
- {FXBSTR_ID('n', 0, 0, 0), &CPDF_StreamContentParser::Handle_EndPath},
- {FXBSTR_ID('q', 0, 0, 0), &CPDF_StreamContentParser::Handle_SaveGraphState},
- {FXBSTR_ID('r', 'e', 0, 0), &CPDF_StreamContentParser::Handle_Rectangle},
- {FXBSTR_ID('r', 'g', 0, 0), &CPDF_StreamContentParser::Handle_SetRGBColor_Fill},
- {FXBSTR_ID('r', 'i', 0, 0), &CPDF_StreamContentParser::Handle_SetRenderIntent},
- {FXBSTR_ID('s', 0, 0, 0), &CPDF_StreamContentParser::Handle_CloseStrokePath},
- {FXBSTR_ID('s', 'c', 0, 0), &CPDF_StreamContentParser::Handle_SetColor_Fill},
- {FXBSTR_ID('s', 'c', 'n', 0), &CPDF_StreamContentParser::Handle_SetColorPS_Fill},
- {FXBSTR_ID('s', 'h', 0, 0), &CPDF_StreamContentParser::Handle_ShadeFill},
- {FXBSTR_ID('v', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_23},
- {FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth},
- {FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13},
-};
-FX_BOOL CPDF_StreamContentParser::OnOperator(FX_LPCSTR op)
-{
- int i = 0;
- FX_DWORD opid = 0;
- while (i < 4 && op[i]) {
- opid = (opid << 8) + op[i];
- i ++;
- }
- while (i < 4) {
- opid <<= 8;
- i ++;
- };
- int low = 0, high = sizeof g_OpCodes / sizeof(struct _OpCode) - 1;
- while (low <= high) {
- int middle = (low + high) / 2;
- int compare = opid - g_OpCodes[middle].m_OpId;
- if (compare == 0) {
- (this->*g_OpCodes[middle].m_OpHandler)();
- return TRUE;
- } else if (compare < 0) {
- high = middle - 1;
- } else {
- low = middle + 1;
- }
- }
- return m_CompatCount != 0;
-}
-void CPDF_StreamContentParser::Handle_CloseFillStrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- Handle_ClosePath();
- AddPathObject(FXFILL_WINDING, TRUE);
-}
-void CPDF_StreamContentParser::Handle_FillStrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(FXFILL_WINDING, TRUE);
-}
-void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE);
- AddPathObject(FXFILL_ALTERNATE, TRUE);
-}
-void CPDF_StreamContentParser::Handle_EOFillStrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(FXFILL_ALTERNATE, TRUE);
-}
-void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary()
-{
- if (!m_Options.m_bMarkedContent) {
- return;
- }
- CFX_ByteString tag = GetString(1);
- CPDF_Object* pProperty = GetObject(0);
- if (pProperty == NULL) {
- return;
- }
- FX_BOOL bDirect = TRUE;
- if (pProperty->GetType() == PDFOBJ_NAME) {
- pProperty = FindResourceObj(FX_BSTRC("Properties"), pProperty->GetString());
- if (pProperty == NULL) {
- return;
- }
- bDirect = FALSE;
- }
- if (pProperty->GetType() != PDFOBJ_DICTIONARY) {
- return;
- }
- m_CurContentMark.GetModify()->AddMark(tag, (CPDF_Dictionary*)pProperty, bDirect);
-}
-void CPDF_StreamContentParser::Handle_BeginMarkedContent()
-{
- if (!m_Options.m_bMarkedContent) {
- return;
- }
- CFX_ByteString tag = GetString(0);
- m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE);
-}
-struct _FX_BSTR {
- FX_LPCSTR m_Ptr;
- int m_Size;
-};
-#define _FX_BSTRC(str) {str, sizeof(str)-1}
-const _FX_BSTR _PDF_InlineKeyAbbr[] = {
- _FX_BSTRC("BitsPerComponent"), _FX_BSTRC("BPC"),
- _FX_BSTRC("ColorSpace"), _FX_BSTRC("CS"),
- _FX_BSTRC("Decode"), _FX_BSTRC("D"),
- _FX_BSTRC("DecodeParms"), _FX_BSTRC("DP"),
- _FX_BSTRC("Filter"), _FX_BSTRC("F"),
- _FX_BSTRC("Height"), _FX_BSTRC("H"),
- _FX_BSTRC("ImageMask"), _FX_BSTRC("IM"),
- _FX_BSTRC("Interpolate"), _FX_BSTRC("I"),
- _FX_BSTRC("Width"), _FX_BSTRC("W"),
-};
-const _FX_BSTR _PDF_InlineValueAbbr[] = {
- _FX_BSTRC("DeviceGray"), _FX_BSTRC("G"),
- _FX_BSTRC("DeviceRGB"), _FX_BSTRC("RGB"),
- _FX_BSTRC("DeviceCMYK"), _FX_BSTRC("CMYK"),
- _FX_BSTRC("Indexed"), _FX_BSTRC("I"),
- _FX_BSTRC("ASCIIHexDecode"), _FX_BSTRC("AHx"),
- _FX_BSTRC("ASCII85Decode"), _FX_BSTRC("A85"),
- _FX_BSTRC("LZWDecode"), _FX_BSTRC("LZW"),
- _FX_BSTRC("FlateDecode"), _FX_BSTRC("Fl"),
- _FX_BSTRC("RunLengthDecode"), _FX_BSTRC("RL"),
- _FX_BSTRC("CCITTFaxDecode"), _FX_BSTRC("CCF"),
- _FX_BSTRC("DCTDecode"), _FX_BSTRC("DCT"),
-};
-static CFX_ByteStringC _PDF_FindFullName(const _FX_BSTR* table, int count, FX_BSTR abbr)
-{
- int i = 0;
- while (i < count) {
- if (abbr.GetLength() == table[i + 1].m_Size && FXSYS_memcmp32(abbr.GetPtr(), table[i + 1].m_Ptr, abbr.GetLength()) == 0) {
- return CFX_ByteStringC(table[i].m_Ptr, table[i].m_Size);
- }
- i += 2;
- }
- return CFX_ByteStringC();
-}
-void _PDF_ReplaceAbbr(CPDF_Object* pObj)
-{
- switch (pObj->GetType()) {
- case PDFOBJ_DICTIONARY: {
- CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
- FX_POSITION pos = pDict->GetStartPos();
- while (pos) {
- CFX_ByteString key;
- CPDF_Object* value = pDict->GetNextElement(pos, key);
- CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineKeyAbbr,
- sizeof _PDF_InlineKeyAbbr / sizeof(_FX_BSTR), key);
- if (!fullname.IsEmpty()) {
- pDict->ReplaceKey(key, fullname);
- key = fullname;
- }
- if (value->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = value->GetString();
- fullname = _PDF_FindFullName(_PDF_InlineValueAbbr,
- sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
- if (!fullname.IsEmpty()) {
- pDict->SetAtName(key, fullname);
- }
- } else {
- _PDF_ReplaceAbbr(value);
- }
- }
- break;
- }
- case PDFOBJ_ARRAY: {
- CPDF_Array* pArray = (CPDF_Array*)pObj;
- for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
- CPDF_Object* pElement = pArray->GetElement(i);
- if (pElement->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = pElement->GetString();
- CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineValueAbbr,
- sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
- if (!fullname.IsEmpty()) {
- pArray->SetAt(i, CPDF_Name::Create(fullname));
- }
- } else {
- _PDF_ReplaceAbbr(pElement);
- }
- }
- break;
- }
- }
-}
-static CFX_ByteStringC _PDF_FindAbbrName(const _FX_BSTR* table, int count, FX_BSTR fullName)
-{
- int i = 0;
- while (i < count) {
- if (fullName.GetLength() == table[i].m_Size && FXSYS_memcmp32(fullName.GetPtr(), table[i].m_Ptr, fullName.GetLength()) == 0) {
- return CFX_ByteStringC(table[i + 1].m_Ptr, table[i + 1].m_Size);
- }
- i += 2;
- }
- return CFX_ByteStringC();
-}
-void _PDF_ReplaceFull(CPDF_Object* pObj)
-{
- switch (pObj->GetType()) {
- case PDFOBJ_DICTIONARY: {
- CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
- FX_POSITION pos = pDict->GetStartPos();
- while (pos) {
- CFX_ByteString key;
- CPDF_Object* value = pDict->GetNextElement(pos, key);
- CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineKeyAbbr,
- sizeof(_PDF_InlineKeyAbbr) / sizeof(_FX_BSTR), key);
- if (!abbrName.IsEmpty()) {
- pDict->ReplaceKey(key, abbrName);
- key = abbrName;
- }
- if (value->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = value->GetString();
- abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr,
- sizeof(_PDF_InlineValueAbbr) / sizeof(_FX_BSTR), name);
- if (!abbrName.IsEmpty()) {
- pDict->SetAtName(key, abbrName);
- }
- } else {
- _PDF_ReplaceFull(value);
- }
- }
- break;
- }
- case PDFOBJ_ARRAY: {
- CPDF_Array* pArray = (CPDF_Array*)pObj;
- for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
- CPDF_Object* pElement = pArray->GetElement(i);
- if (pElement->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = pElement->GetString();
- CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr,
- sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
- if (!abbrName.IsEmpty()) {
- pArray->SetAt(i, CPDF_Name::Create(abbrName));
- }
- } else {
- _PDF_ReplaceFull(pElement);
- }
- }
- break;
- }
- }
-}
-void CPDF_StreamContentParser::Handle_BeginText()
-{
- m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0);
- OnChangeTextMatrix();
- m_pCurStates->m_TextX = 0;
- m_pCurStates->m_TextY = 0;
- m_pCurStates->m_TextLineX = 0;
- m_pCurStates->m_TextLineY = 0;
-}
-void CPDF_StreamContentParser::Handle_BeginSectionUndefined()
-{
- m_CompatCount ++;
-}
-void CPDF_StreamContentParser::Handle_CurveTo_123()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO);
- AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
-}
-void CPDF_StreamContentParser::Handle_ConcatMatrix()
-{
- FX_FLOAT a2 = GetNumber16(5), b2 = GetNumber16(4), c2 = GetNumber16(3), d2 = GetNumber16(2);
- FX_FLOAT e2 = GetNumber(1), f2 = GetNumber(0);
- FX_FLOAT old_width_scale = m_pCurStates->m_CTM.GetXUnit();
- CFX_AffineMatrix new_matrix(a2, b2, c2, d2, e2, f2);
- new_matrix.Concat(m_pCurStates->m_CTM);
- m_pCurStates->m_CTM = new_matrix;
- FX_FLOAT new_width_scale = m_pCurStates->m_CTM.GetXUnit();
- OnChangeTextMatrix();
-}
-void CPDF_StreamContentParser::Handle_SetColorSpace_Fill()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CFX_ByteString csname = GetString(0);
- CPDF_ColorSpace* pCS = FindColorSpace(csname);
- if (pCS == NULL) {
- return;
- }
- m_pCurStates->m_ColorState.GetModify()->m_FillColor.SetColorSpace(pCS);
-}
-void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CFX_ByteString csname = GetString(0);
- CPDF_ColorSpace* pCS = FindColorSpace(csname);
- if (pCS == NULL) {
- return;
- }
- m_pCurStates->m_ColorState.GetModify()->m_StrokeColor.SetColorSpace(pCS);
-}
-void CPDF_StreamContentParser::Handle_SetDash()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CPDF_Array* pArray = GetObject(1)->GetArray();
- if (pArray == NULL) {
- return;
- }
- m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f);
-}
-void CPDF_StreamContentParser::Handle_SetCharWidth()
-{
- m_Type3Data[0] = GetNumber(1);
- m_Type3Data[1] = GetNumber(0);
- m_bColored = TRUE;
-}
-void CPDF_StreamContentParser::Handle_SetCachedDevice()
-{
- for (int i = 0; i < 6; i ++) {
- m_Type3Data[i] = GetNumber(5 - i);
- }
- m_bColored = FALSE;
-}
-void CPDF_StreamContentParser::Handle_ExecuteXObject()
-{
- CFX_ByteString name = GetString(0);
- if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && m_pLastImage->GetStream()->GetObjNum()) {
-#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_)
- AddDuplicateImage();
-#else
- AddImage(NULL, m_pLastImage, FALSE);
-#endif
- return;
- }
- if (m_Options.m_bTextOnly) {
- CPDF_Object* pRes = NULL;
- if (m_pResources == NULL) {
- return;
- }
- if (m_pResources == m_pPageResources) {
- CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject"));
- if (pList == NULL) {
- return;
- }
- pRes = pList->GetElement(name);
- if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
- return;
- }
- } else {
- CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject"));
- if (pList == NULL) {
- if (m_pPageResources == NULL) {
- return;
- }
- CPDF_Dictionary* pList = m_pPageResources->GetDict(FX_BSTRC("XObject"));
- if (pList == NULL) {
- return;
- }
- pRes = pList->GetElement(name);
- if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
- return;
- }
- } else {
- pRes = pList->GetElement(name);
- if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
- return;
- }
- }
- }
- FX_BOOL bForm;
- if (m_pDocument->IsFormStream(((CPDF_Reference*)pRes)->GetRefObjNum(), bForm) && !bForm) {
- return;
- }
- }
- CPDF_Stream* pXObject = (CPDF_Stream*)FindResourceObj(FX_BSTRC("XObject"), name);
- if (pXObject == NULL || pXObject->GetType() != PDFOBJ_STREAM) {
- m_bResourceMissing = TRUE;
- return;
- }
- CFX_ByteStringC type = pXObject->GetDict()->GetConstString(FX_BSTRC("Subtype"));
- if (type == FX_BSTRC("Image")) {
- if (m_Options.m_bTextOnly) {
- return;
- }
- CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE);
- m_LastImageName = name;
- m_pLastImage = pObj->m_pImage;
- } else if (type == FX_BSTRC("Form")) {
- AddForm(pXObject);
- } else {
- return;
- }
-}
-void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream)
-{
-#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
- if (!m_Options.m_bSeparateForm) {
- CPDF_Dictionary* pResources = pStream->GetDict()->GetDict(FX_BSTRC("Resources"));
- CFX_AffineMatrix form_matrix = pStream->GetDict()->GetMatrix(FX_BSTRC("Matrix"));
- form_matrix.Concat(m_pCurStates->m_CTM);
- CPDF_Array* pBBox = pStream->GetDict()->GetArray(FX_BSTRC("BBox"));
- CFX_FloatRect form_bbox;
- CPDF_Path ClipPath;
- if (pBBox) {
- form_bbox = pStream->GetDict()->GetRect(FX_BSTRC("BBox"));
- ClipPath.New();
- ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top);
- ClipPath.Transform(&form_matrix);
- form_bbox.Transform(&form_matrix);
- }
- CPDF_StreamContentParser parser;
- parser.Initialize();
- parser.PrepareParse(m_pDocument, m_pPageResources, m_pResources, &m_mtContentToUser,
- m_pObjectList, pResources, &form_bbox, &m_Options, m_pCurStates, m_Level + 1);
- parser.m_pCurStates->m_CTM = form_matrix;
- if (ClipPath.NotNull()) {
- parser.m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE);
- }
- CPDF_StreamAcc stream;
- stream.LoadAllData(pStream, FALSE);
- if (stream.GetSize() == 0) {
- return;
- }
-#ifdef _FPDFAPI_MINI_
- parser.InputData(stream.GetData(), stream.GetSize());
- parser.Finish();
-#else
- parser.Parse(stream.GetData(), stream.GetSize(), 0);
-#endif
- return;
- }
-#endif
- CPDF_FormObject* pFormObj = FX_NEW CPDF_FormObject;
- pFormObj->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources);
- pFormObj->m_FormMatrix = m_pCurStates->m_CTM;
- pFormObj->m_FormMatrix.Concat(m_mtContentToUser);
- CPDF_AllStates status;
- status.m_GeneralState = m_pCurStates->m_GeneralState;
- status.m_GraphState = m_pCurStates->m_GraphState;
- status.m_ColorState = m_pCurStates->m_ColorState;
- status.m_TextState = m_pCurStates->m_TextState;
- pFormObj->m_pForm->ParseContent(&status, NULL, NULL, &m_Options, m_Level + 1);
- if (!m_pObjectList->m_bBackgroundAlphaNeeded && pFormObj->m_pForm->m_bBackgroundAlphaNeeded) {
- m_pObjectList->m_bBackgroundAlphaNeeded = TRUE;
- }
- pFormObj->CalcBoundingBox();
- SetGraphicStates(pFormObj, TRUE, TRUE, TRUE);
- m_pObjectList->m_ObjectList.AddTail(pFormObj);
-}
-#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_)
-void CPDF_StreamContentParser::AddDuplicateImage()
-{
- FX_POSITION tailpos = m_pObjectList->m_ObjectList.GetTailPosition();
- CPDF_PageObject* pLastObj = (CPDF_PageObject*)m_pObjectList->m_ObjectList.GetAt(tailpos);
- if (pLastObj == NULL || (pLastObj->m_Type != PDFPAGE_INLINES && pLastObj->m_Type != PDFPAGE_IMAGE)) {
- AddImage(NULL, m_pLastImage, FALSE);
- return;
- }
- if (pLastObj->m_GeneralState != m_pCurStates->m_GeneralState ||
- pLastObj->m_ClipPath != m_pCurStates->m_ClipPath ||
- pLastObj->m_ColorState != m_pCurStates->m_ColorState) {
- AddImage(NULL, m_pLastImage, FALSE);
- return;
- }
- CFX_AffineMatrix ImageMatrix;
- ImageMatrix.Copy(m_pCurStates->m_CTM);
- ImageMatrix.Concat(m_mtContentToUser);
- if (pLastObj->m_Type == PDFPAGE_INLINES) {
- CPDF_InlineImages* pInlines = (CPDF_InlineImages*)pLastObj;
- if (pInlines->m_pStream != m_pLastImage->GetStream()) {
- AddImage(NULL, m_pLastImage, FALSE);
- return;
- }
- pInlines->AddMatrix(ImageMatrix);
- } else {
- CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pLastObj;
- CPDF_InlineImages* pInlines = FX_NEW CPDF_InlineImages;
- pInlines->m_pStream = m_pLastImage->GetStream();
- SetGraphicStates(pInlines, !pInlines->m_pStream->GetDict()->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE);
- pInlines->AddMatrix(pImageObj->m_Matrix);
- pInlines->AddMatrix(ImageMatrix);
- m_pObjectList->m_ObjectList.RemoveAt(tailpos);
- m_pObjectList->m_ObjectList.AddTail(pInlines);
- pLastObj->Release();
- }
-}
-#endif
-CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, CPDF_Image* pImage, FX_BOOL bInline)
-{
- if (pStream == NULL && pImage == NULL) {
- return NULL;
- }
- CFX_AffineMatrix ImageMatrix;
- ImageMatrix.Copy(m_pCurStates->m_CTM);
- ImageMatrix.Concat(m_mtContentToUser);
- CPDF_ImageObject* pImageObj = FX_NEW CPDF_ImageObject;
- if (pImage) {
- pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pImage->GetStream());
- } else if (pStream->GetObjNum()) {
- pImageObj->m_pImage = m_pDocument->LoadImageF(pStream);
- } else {
- pImageObj->m_pImage = FX_NEW CPDF_Image(m_pDocument);
- pImageObj->m_pImage->LoadImageF(pStream, bInline);
- }
- SetGraphicStates(pImageObj, pImageObj->m_pImage->IsMask(), FALSE, FALSE);
- pImageObj->m_Matrix = ImageMatrix;
- pImageObj->CalcBoundingBox();
- m_pObjectList->m_ObjectList.AddTail(pImageObj);
- return pImageObj;
-}
-void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary()
-{
-}
-void CPDF_StreamContentParser::Handle_EndImage()
-{
-}
-void CPDF_StreamContentParser::Handle_EndMarkedContent()
-{
- if (!m_Options.m_bMarkedContent) {
- return;
- }
- if (m_CurContentMark.IsNull()) {
- return;
- }
- int count = m_CurContentMark.GetObject()->CountItems();
- if (count == 1) {
- m_CurContentMark.SetNull();
- return;
- }
- m_CurContentMark.GetModify()->DeleteLastMark();
-}
-void CPDF_StreamContentParser::Handle_EndText()
-{
- int count = m_ClipTextList.GetSize();
- if (count == 0) {
- return;
- }
- if (m_pCurStates->m_TextState.GetObject()->m_TextMode < 4) {
- for (int i = 0; i < count; i ++) {
- CPDF_TextObject* pText = (CPDF_TextObject*)m_ClipTextList.GetAt(i);
- if (pText) {
- delete pText;
- }
- }
- } else {
- m_pCurStates->m_ClipPath.AppendTexts((CPDF_TextObject**)m_ClipTextList.GetData(), count);
- }
- m_ClipTextList.RemoveAll();
-}
-void CPDF_StreamContentParser::Handle_EndSectionUndefined()
-{
- if (m_CompatCount) {
- m_CompatCount --;
- }
-}
-void CPDF_StreamContentParser::Handle_FillPath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(FXFILL_WINDING, FALSE);
-}
-void CPDF_StreamContentParser::Handle_FillPathOld()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(FXFILL_WINDING, FALSE);
-}
-void CPDF_StreamContentParser::Handle_EOFillPath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(FXFILL_ALTERNATE, FALSE);
-}
-void CPDF_StreamContentParser::Handle_SetGray_Fill()
-{
- FX_FLOAT value = GetNumber(0);
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
- m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1);
-}
-void CPDF_StreamContentParser::Handle_SetGray_Stroke()
-{
- FX_FLOAT value = GetNumber(0);
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
- m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1);
-}
-void CPDF_StreamContentParser::Handle_SetExtendGraphState()
-{
- CFX_ByteString name = GetString(0);
- CPDF_Dictionary* pGS = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("ExtGState"), name);
- if (pGS == NULL || pGS->GetType() != PDFOBJ_DICTIONARY) {
- m_bResourceMissing = TRUE;
- return;
- }
- m_pCurStates->ProcessExtGS(pGS, this);
-}
-void CPDF_StreamContentParser::Handle_ClosePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- if (m_PathPointCount == 0) {
- return;
- }
- if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) {
- AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE);
- } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) {
- m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
- }
-}
-void CPDF_StreamContentParser::Handle_SetFlat()
-{
-#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
- m_pCurStates->m_GeneralState.GetModify()->m_Flatness = GetNumber(0);
-#endif
-}
-void CPDF_StreamContentParser::Handle_BeginImageData()
-{
-}
-void CPDF_StreamContentParser::Handle_SetLineJoin()
-{
- m_pCurStates->m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)GetInteger(0);
-}
-void CPDF_StreamContentParser::Handle_SetLineCap()
-{
- m_pCurStates->m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)GetInteger(0);
-}
-void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill()
-{
- REQUIRE_PARAMS(4);
- FX_FLOAT values[4];
- for (int i = 0; i < 4; i ++) {
- values[i] = GetNumber(3 - i);
- }
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4);
-}
-void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke()
-{
- REQUIRE_PARAMS(4);
- FX_FLOAT values[4];
- for (int i = 0; i < 4; i ++) {
- values[i] = GetNumber(3 - i);
- }
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4);
-}
-void CPDF_StreamContentParser::Handle_LineTo()
-{
- REQUIRE_PARAMS(2);
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO);
-}
-void CPDF_StreamContentParser::Handle_MoveTo()
-{
- REQUIRE_PARAMS(2);
- if (m_Options.m_bTextOnly) {
-#ifndef _FPDFAPI_MINI_
- m_pSyntax->SkipPathObject();
-#endif
- return;
- }
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO);
-#ifndef _FPDFAPI_MINI_
- ParsePathObject();
-#endif
-}
-void CPDF_StreamContentParser::Handle_SetMiterLimit()
-{
- m_pCurStates->m_GraphState.GetModify()->m_MiterLimit = GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_MarkPlace()
-{
-}
-void CPDF_StreamContentParser::Handle_EndPath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(0, FALSE);
-}
-void CPDF_StreamContentParser::Handle_SaveGraphState()
-{
- CPDF_AllStates* pStates = FX_NEW CPDF_AllStates;
- pStates->Copy(*m_pCurStates);
- m_StateStack.Add(pStates);
-}
-void CPDF_StreamContentParser::Handle_RestoreGraphState()
-{
- int size = m_StateStack.GetSize();
- if (size == 0) {
- return;
- }
- CPDF_AllStates* pStates = (CPDF_AllStates*)m_StateStack.GetAt(size - 1);
- m_pCurStates->Copy(*pStates);
- delete pStates;
- m_StateStack.RemoveAt(size - 1);
-}
-void CPDF_StreamContentParser::Handle_Rectangle()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- FX_FLOAT x = GetNumber(3), y = GetNumber(2);
- FX_FLOAT w = GetNumber(1), h = GetNumber(0);
- AddPathRect(x, y, w, h);
-}
-void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h)
-{
- AddPathPoint(x, y, FXPT_MOVETO);
- AddPathPoint(x + w, y, FXPT_LINETO);
- AddPathPoint(x + w, y + h, FXPT_LINETO);
- AddPathPoint(x, y + h, FXPT_LINETO);
- AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE);
-}
-void CPDF_StreamContentParser::Handle_SetRGBColor_Fill()
-{
- REQUIRE_PARAMS(3);
- FX_FLOAT values[3];
- for (int i = 0; i < 3; i ++) {
- values[i] = GetNumber(2 - i);
- }
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
- m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3);
-}
-void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke()
-{
- REQUIRE_PARAMS(3);
- FX_FLOAT values[3];
- for (int i = 0; i < 3; i ++) {
- values[i] = GetNumber(2 - i);
- }
- CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
- m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3);
-}
-void CPDF_StreamContentParser::Handle_SetRenderIntent()
-{
-}
-void CPDF_StreamContentParser::Handle_CloseStrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- Handle_ClosePath();
- AddPathObject(0, TRUE);
-}
-void CPDF_StreamContentParser::Handle_StrokePath()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathObject(0, TRUE);
-}
-void CPDF_StreamContentParser::Handle_SetColor_Fill()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- FX_FLOAT values[4];
- int nargs = m_ParamCount;
- if (nargs > 4) {
- nargs = 4;
- }
- for (int i = 0; i < nargs; i ++) {
- values[i] = GetNumber(nargs - i - 1);
- }
- m_pCurStates->m_ColorState.SetFillColor(NULL, values, nargs);
-}
-void CPDF_StreamContentParser::Handle_SetColor_Stroke()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- FX_FLOAT values[4];
- int nargs = m_ParamCount;
- if (nargs > 4) {
- nargs = 4;
- }
- for (int i = 0; i < nargs; i ++) {
- values[i] = GetNumber(nargs - i - 1);
- }
- m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nargs);
-}
-void CPDF_StreamContentParser::Handle_SetColorPS_Fill()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CPDF_Object* pLastParam = GetObject(0);
- if (pLastParam == NULL) {
- return;
- }
- int nargs = m_ParamCount;
- int nvalues = nargs;
- if (pLastParam->GetType() == PDFOBJ_NAME) {
- nvalues --;
- }
- FX_FLOAT* values = NULL;
- if (nvalues) {
- values = FX_Alloc(FX_FLOAT, nvalues);
- for (int i = 0; i < nvalues; i ++) {
- values[i] = GetNumber(nargs - i - 1);
- }
- }
- if (nvalues != nargs) {
- CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE);
- if (pPattern) {
- m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues);
- }
- } else {
- m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues);
- }
- if (values) {
- FX_Free(values);
- }
-}
-void CPDF_StreamContentParser::Handle_SetColorPS_Stroke()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CPDF_Object* pLastParam = GetObject(0);
- if (pLastParam == NULL) {
- return;
- }
- int nargs = m_ParamCount;
- int nvalues = nargs;
- if (pLastParam->GetType() == PDFOBJ_NAME) {
- nvalues --;
- }
- FX_FLOAT* values = NULL;
- if (nvalues) {
- values = FX_Alloc(FX_FLOAT, nvalues);
- for (int i = 0; i < nvalues; i ++) {
- values[i] = GetNumber(nargs - i - 1);
- }
- }
- if (nvalues != nargs) {
- CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE);
- if (pPattern) {
- m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues);
- }
- } else {
- m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues);
- }
- if (values) {
- FX_Free(values);
- }
-}
-CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix,
- CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS);
-void CPDF_StreamContentParser::Handle_ShadeFill()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE);
- if (pPattern == NULL) {
- return;
- }
- if (pPattern->m_PatternType != PATTERN_SHADING) {
- return;
- }
- CPDF_ShadingPattern* pShading = (CPDF_ShadingPattern*)pPattern;
- if (!pShading->m_bShadingObj) {
- return;
- }
- if (!pShading->Load()) {
- return;
- }
- CPDF_ShadingObject* pObj = FX_NEW CPDF_ShadingObject;
- pObj->m_pShading = pShading;
- SetGraphicStates(pObj, FALSE, FALSE, FALSE);
- pObj->m_Matrix = m_pCurStates->m_CTM;
- pObj->m_Matrix.Concat(m_mtContentToUser);
- CFX_FloatRect bbox;
- if (!pObj->m_ClipPath.IsNull()) {
- bbox = pObj->m_ClipPath.GetClipBox();
- } else {
- bbox = m_BBox;
- }
- if (pShading->m_ShadingType >= 4) {
- bbox.Intersect(_GetShadingBBox((CPDF_Stream*)pShading->m_pShadingObj, pShading->m_ShadingType, &pObj->m_Matrix,
- pShading->m_pFunctions, pShading->m_nFuncs, pShading->m_pCS));
- }
- pObj->m_Left = bbox.left;
- pObj->m_Right = bbox.right;
- pObj->m_Top = bbox.top;
- pObj->m_Bottom = bbox.bottom;
- m_pObjectList->m_ObjectList.AddTail(pObj);
-}
-void CPDF_StreamContentParser::Handle_SetCharSpace()
-{
- m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_MoveTextPoint()
-{
- m_pCurStates->m_TextLineX += GetNumber(1);
- m_pCurStates->m_TextLineY += GetNumber(0);
- m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
- m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
-}
-void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading()
-{
- Handle_MoveTextPoint();
- m_pCurStates->m_TextLeading = -GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_SetFont()
-{
- FX_FLOAT fs = GetNumber(0);
- if (fs == 0) {
- fs = m_DefFontSize;
- }
- m_pCurStates->m_TextState.GetModify()->m_FontSize = fs;
- CPDF_Font* pFont = FindFont(GetString(1));
- if (pFont) {
- m_pCurStates->m_TextState.SetFont(pFont);
- }
-}
-CPDF_Object* CPDF_StreamContentParser::FindResourceObj(FX_BSTR type, const CFX_ByteString& name)
-{
- if (m_pResources == NULL) {
- return NULL;
- }
- if (m_pResources == m_pPageResources) {
- CPDF_Dictionary* pList = m_pResources->GetDict(type);
- if (pList == NULL) {
- return NULL;
- }
- CPDF_Object* pRes = pList->GetElementValue(name);
- return pRes;
- }
- CPDF_Dictionary* pList = m_pResources->GetDict(type);
- if (pList == NULL) {
- if (m_pPageResources == NULL) {
- return NULL;
- }
- CPDF_Dictionary* pList = m_pPageResources->GetDict(type);
- if (pList == NULL) {
- return NULL;
- }
- CPDF_Object* pRes = pList->GetElementValue(name);
- return pRes;
- }
- CPDF_Object* pRes = pList->GetElementValue(name);
- return pRes;
-}
-CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name)
-{
- CPDF_Dictionary* pFontDict = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("Font"), name);
- if (pFontDict == NULL || pFontDict->GetType() != PDFOBJ_DICTIONARY) {
- m_bResourceMissing = TRUE;
- return CPDF_Font::GetStockFont(m_pDocument, FX_BSTRC("Helvetica"));
- }
- CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict);
- if (pFont && pFont->GetType3Font()) {
- pFont->GetType3Font()->SetPageResources(m_pResources);
- pFont->GetType3Font()->CheckType3FontMetrics();
- }
- return pFont;
-}
-CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace(const CFX_ByteString& name)
-{
- if (name == FX_BSTRC("Pattern")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
- }
- if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("DeviceRGB")) {
- CFX_ByteString defname = "Default";
- defname += name.Mid(7);
- CPDF_Object* pDefObj = FindResourceObj(FX_BSTRC("ColorSpace"), defname);
- if (pDefObj == NULL) {
- if (name == FX_BSTRC("DeviceGray")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
- }
- if (name == FX_BSTRC("DeviceRGB")) {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
- }
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- }
- return m_pDocument->LoadColorSpace(pDefObj);
- }
- CPDF_Object* pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
- if (pCSObj == NULL) {
- m_bResourceMissing = TRUE;
- return NULL;
- }
- return m_pDocument->LoadColorSpace(pCSObj);
-}
-CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, FX_BOOL bShading)
-{
- CPDF_Object* pPattern = FindResourceObj(bShading ? FX_BSTRC("Shading") : FX_BSTRC("Pattern"), name);
- if (pPattern == NULL || (pPattern->GetType() != PDFOBJ_DICTIONARY &&
- pPattern->GetType() != PDFOBJ_STREAM)) {
- m_bResourceMissing = TRUE;
- return NULL;
- }
- return m_pDocument->LoadPattern(pPattern, bShading, &m_pCurStates->m_ParentMatrix);
-}
-void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y)
-{
- m_pCurStates->m_TextMatrix.Transform(x, y, x, y);
- ConvertUserSpace(x, y);
-}
-void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y)
-{
- m_pCurStates->m_CTM.Transform(x, y, x, y);
- m_mtContentToUser.Transform(x, y, x, y);
-}
-void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int nsegs)
-{
- CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont();
- if (pFont == NULL) {
- return;
- }
- if (fInitKerning != 0) {
- if (!pFont->IsVertWriting()) {
- m_pCurStates->m_TextX -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000;
- } else {
- m_pCurStates->m_TextY -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000;
- }
- }
- if (nsegs == 0) {
- return;
- }
- int textmode;
- if (pFont->GetFontType() == PDFFONT_TYPE3) {
- textmode = 0;
- } else {
- textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode;
- }
- CPDF_TextObject* pText = FX_NEW CPDF_TextObject;
- m_pLastTextObject = pText;
- SetGraphicStates(pText, TRUE, TRUE, TRUE);
- if (textmode && textmode != 3 && textmode != 4 && textmode != 7) {
- FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM;
- pCTM[0] = m_pCurStates->m_CTM.a;
- pCTM[1] = m_pCurStates->m_CTM.c;
- pCTM[2] = m_pCurStates->m_CTM.b;
- pCTM[3] = m_pCurStates->m_CTM.d;
- }
- pText->SetSegments(pStrs, pKerning, nsegs);
- pText->m_PosX = m_pCurStates->m_TextX;
- pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise;
- ConvertTextSpace(pText->m_PosX, pText->m_PosY);
- FX_FLOAT x_advance, y_advance;
- pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale, m_Level);
- m_pCurStates->m_TextX += x_advance;
- m_pCurStates->m_TextY += y_advance;
- if (textmode > 3) {
- CPDF_TextObject* pCopy = FX_NEW CPDF_TextObject;
- pCopy->Copy(pText);
- m_ClipTextList.Add(pCopy);
- }
- m_pObjectList->m_ObjectList.AddTail(pText);
- if (pKerning && pKerning[nsegs - 1] != 0) {
- if (!pFont->IsVertWriting()) {
- m_pCurStates->m_TextX -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000;
- } else {
- m_pCurStates->m_TextY -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000;
- }
- }
-}
-void CPDF_StreamContentParser::Handle_ShowText()
-{
- CFX_ByteString str = GetString(0);
- if (str.IsEmpty()) {
- return;
- }
- AddTextObject(&str, 0, NULL, 1);
-}
-void CPDF_StreamContentParser::Handle_ShowText_Positioning()
-{
- CPDF_Array* pArray = GetObject(0)->GetArray();
- if (pArray == NULL) {
- return;
- }
- int n = pArray->GetCount(), nsegs = 0, i;
- for (i = 0; i < n; i ++) {
- CPDF_Object* pObj = pArray->GetElementValue(i);
- if (pObj->GetType() == PDFOBJ_STRING) {
- nsegs ++;
- }
- }
- if (nsegs == 0) {
- for (i = 0; i < n; i ++) {
- m_pCurStates->m_TextX -= FXSYS_Mul(pArray->GetNumber(i), m_pCurStates->m_TextState.GetFontSize()) / 1000;
- };
- return;
- }
- CFX_ByteString* pStrs;
- FX_NEW_VECTOR(pStrs, CFX_ByteString, nsegs);
- FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs);
- int iSegment = 0;
- FX_FLOAT fInitKerning = 0;
- for (i = 0; i < n; i ++) {
- CPDF_Object* pObj = pArray->GetElementValue(i);
- if (pObj->GetType() == PDFOBJ_STRING) {
- CFX_ByteString str = pObj->GetString();
- if (str.IsEmpty()) {
- continue;
- }
- pStrs[iSegment] = str;
- pKerning[iSegment ++] = 0;
- } else {
- if (iSegment == 0) {
- fInitKerning += pObj->GetNumber();
- } else {
- pKerning[iSegment - 1] += pObj->GetNumber();
- }
- }
- }
- AddTextObject(pStrs, fInitKerning, pKerning, iSegment);
- FX_DELETE_VECTOR(pStrs, CFX_ByteString, nsegs);
- FX_Free(pKerning);
-}
-void CPDF_StreamContentParser::Handle_SetTextLeading()
-{
- m_pCurStates->m_TextLeading = GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_SetTextMatrix()
-{
- m_pCurStates->m_TextMatrix.Set(GetNumber16(5), GetNumber16(4), GetNumber16(3),
- GetNumber16(2), GetNumber(1), GetNumber(0));
- OnChangeTextMatrix();
- m_pCurStates->m_TextX = 0;
- m_pCurStates->m_TextY = 0;
- m_pCurStates->m_TextLineX = 0;
- m_pCurStates->m_TextLineY = 0;
-}
-void CPDF_StreamContentParser::OnChangeTextMatrix()
-{
- CFX_AffineMatrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
- text_matrix.Concat(m_pCurStates->m_TextMatrix);
- text_matrix.Concat(m_pCurStates->m_CTM);
- text_matrix.Concat(m_mtContentToUser);
- FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetModify()->m_Matrix;
- pTextMatrix[0] = text_matrix.a;
- pTextMatrix[1] = text_matrix.c;
- pTextMatrix[2] = text_matrix.b;
- pTextMatrix[3] = text_matrix.d;
-}
-void CPDF_StreamContentParser::Handle_SetTextRenderMode()
-{
- int mode = GetInteger(0);
- if (mode < 0 || mode > 7) {
- return;
- }
- m_pCurStates->m_TextState.GetModify()->m_TextMode = mode;
-}
-void CPDF_StreamContentParser::Handle_SetTextRise()
-{
- m_pCurStates->m_TextRise = GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_SetWordSpace()
-{
- m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(0);
-}
-void CPDF_StreamContentParser::Handle_SetHorzScale()
-{
- if (m_ParamCount != 1) {
- return;
- }
- m_pCurStates->m_TextHorzScale = GetNumber(0) / 100;
- OnChangeTextMatrix();
-}
-void CPDF_StreamContentParser::Handle_MoveToNextLine()
-{
- m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading;
- m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
- m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
-}
-void CPDF_StreamContentParser::Handle_CurveTo_23()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
- AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
-}
-void CPDF_StreamContentParser::Handle_SetLineWidth()
-{
- FX_FLOAT width = GetNumber(0);
- m_pCurStates->m_GraphState.GetModify()->m_LineWidth = width;
-}
-void CPDF_StreamContentParser::Handle_Clip()
-{
- m_PathClipType = FXFILL_WINDING;
-}
-void CPDF_StreamContentParser::Handle_EOClip()
-{
- m_PathClipType = FXFILL_ALTERNATE;
-}
-void CPDF_StreamContentParser::Handle_CurveTo_13()
-{
- if (m_Options.m_bTextOnly) {
- return;
- }
- AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
- AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
-}
-void CPDF_StreamContentParser::Handle_NextLineShowText()
-{
- Handle_MoveToNextLine();
- Handle_ShowText();
-}
-void CPDF_StreamContentParser::Handle_NextLineShowText_Space()
-{
- m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(2);
- m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(1);
- Handle_NextLineShowText();
-}
-void CPDF_StreamContentParser::Handle_Invalid()
-{
-}
-void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag)
-{
- m_PathCurrentX = x;
- m_PathCurrentY = y;
- if (flag == FXPT_MOVETO) {
- m_PathStartX = x;
- m_PathStartY = y;
- if (m_PathPointCount && m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) {
- m_pPathPoints[m_PathPointCount - 1].m_PointX = x;
- m_pPathPoints[m_PathPointCount - 1].m_PointY = y;
- return;
- }
- } else if (m_PathPointCount == 0) {
- return;
- }
- m_PathPointCount ++;
- if (m_PathPointCount > m_PathAllocSize) {
- int newsize = m_PathPointCount + 256;
- FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize);
- if (m_PathAllocSize) {
- FXSYS_memcpy32(pNewPoints, m_pPathPoints, m_PathAllocSize * sizeof(FX_PATHPOINT));
- FX_Free(m_pPathPoints);
- }
- m_pPathPoints = pNewPoints;
- m_PathAllocSize = newsize;
- }
- m_pPathPoints[m_PathPointCount - 1].m_Flag = flag;
- m_pPathPoints[m_PathPointCount - 1].m_PointX = x;
- m_pPathPoints[m_PathPointCount - 1].m_PointY = y;
-}
-void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke)
-{
- int PathPointCount = m_PathPointCount, PathClipType = m_PathClipType;
- m_PathPointCount = 0;
- m_PathClipType = 0;
- if (PathPointCount <= 1) {
- if (PathPointCount && PathClipType) {
- CPDF_Path path;
- path.New()->AppendRect(0, 0, 0, 0);
- m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE);
- }
- return;
- }
- if (PathPointCount && m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) {
- PathPointCount --;
- }
- CPDF_Path Path;
- CFX_PathData* pPathData = Path.New();
- pPathData->SetPointCount(PathPointCount);
- FXSYS_memcpy32(pPathData->GetPoints(), m_pPathPoints, sizeof(FX_PATHPOINT) * PathPointCount);
- CFX_AffineMatrix matrix = m_pCurStates->m_CTM;
- matrix.Concat(m_mtContentToUser);
- if (bStroke || FillType) {
- CPDF_PathObject* pPathObj = FX_NEW CPDF_PathObject;
- pPathObj->m_bStroke = bStroke;
- pPathObj->m_FillType = FillType;
- pPathObj->m_Path = Path;
- pPathObj->m_Matrix = matrix;
- SetGraphicStates(pPathObj, TRUE, FALSE, TRUE);
- pPathObj->CalcBoundingBox();
- m_pObjectList->m_ObjectList.AddTail(pPathObj);
- }
- if (PathClipType) {
- if (!matrix.IsIdentity()) {
- Path.Transform(&matrix);
- matrix.SetIdentity();
- }
- m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE);
- }
-}
-CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf)
-{
- CFX_ByteTextBuf buf;
- FX_BOOL bFirst = TRUE;
- int code = 0;
- FX_LPCBYTE str = src_buf.GetBuffer();
- FX_DWORD size = src_buf.GetSize();
- for (FX_DWORD i = 0; i < size; i ++) {
- FX_BYTE ch = str[i];
- if (ch >= '0' && ch <= '9') {
- if (bFirst) {
- code = (ch - '0') * 16;
- } else {
- code += ch - '0';
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- } else if (ch >= 'A' && ch <= 'F') {
- if (bFirst) {
- code = (ch - 'A' + 10) * 16;
- } else {
- code += ch - 'A' + 10;
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- } else if (ch >= 'a' && ch <= 'f') {
- if (bFirst) {
- code = (ch - 'a' + 10) * 16;
- } else {
- code += ch - 'a' + 10;
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- }
- }
- if (!bFirst) {
- buf.AppendChar((char)code);
- }
- return buf.GetByteString();
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fpdfapi/fpdf_serial.h" +#include "pageint.h" +#define REQUIRE_PARAMS(count) if (m_ParamCount != count) { m_bAbort = TRUE; return; } +CPDF_StreamContentParser::CPDF_StreamContentParser() +{ + m_DefFontSize = 0; + m_pCurStates = NULL; + m_pLastTextObject = NULL; + m_pPathPoints = NULL; + m_PathClipType = 0; + m_PathPointCount = m_PathAllocSize = 0; + m_PathCurrentX = m_PathCurrentY = 0.0f; + m_bResourceMissing = FALSE; + m_bColored = FALSE; + FXSYS_memset32(m_Type3Data, 0, sizeof(FX_FLOAT) * 6); + m_ParamCount = 0; + m_ParamStartPos = 0; + m_bAbort = FALSE; + m_pLastImageDict = NULL; + m_pLastCloneImageDict = NULL; + m_pLastImage = NULL; + m_bReleaseLastDict = TRUE; + m_pParentResources = NULL; +#ifdef _FPDFAPI_MINI_ + m_pObjectState = NULL; + m_pObjectStack = NULL; + m_pWordBuf = NULL; + m_pDictName = NULL; + m_pStreamBuf = NULL; + m_WordState = 0; + m_ObjectSize = 0; +#endif +} +FX_BOOL CPDF_StreamContentParser::Initialize() +{ +#ifdef _FPDFAPI_MINI_ + m_pObjectState = FX_Alloc(FX_BOOL, _FPDF_MAX_OBJECT_STACK_SIZE_); + FXSYS_memset32(m_pObjectState, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(FX_BOOL)); + m_pObjectStack = FX_Alloc(CPDF_Object*, _FPDF_MAX_OBJECT_STACK_SIZE_); + FXSYS_memset32(m_pObjectStack, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(CPDF_Object*)); + m_pWordBuf = FX_Alloc(FX_BYTE, 256); + FXSYS_memset32(m_pWordBuf, 0, 256 * sizeof(FX_BYTE)); + m_pDictName = FX_Alloc(FX_BYTE, 256); + FXSYS_memset32(m_pDictName, 0, 256 * sizeof(FX_BYTE)); + m_pStreamBuf = FX_Alloc(FX_BYTE, STREAM_PARSE_BUFSIZE); + FXSYS_memset32(m_pStreamBuf, 0, STREAM_PARSE_BUFSIZE * sizeof(FX_BYTE)); + m_StringBuf.EstimateSize(1024); + m_ObjectSize = 0; + m_ImageSrcBuf.EstimateSize(STREAM_PARSE_BUFSIZE); +#endif + return TRUE; +} +CPDF_StreamContentParser::~CPDF_StreamContentParser() +{ + ClearAllParams(); + int i = 0; + for (i = 0; i < m_StateStack.GetSize(); i ++) { + delete (CPDF_AllStates*)m_StateStack[i]; + } + if (m_pPathPoints) { + FX_Free(m_pPathPoints); + } + if (m_pCurStates) { + delete m_pCurStates; + } + if (m_pLastImageDict) { + m_pLastImageDict->Release(); + } + if (m_pLastCloneImageDict) { + m_pLastCloneImageDict->Release(); + } +#ifdef _FPDFAPI_MINI_ + for (i = 0; i < (int)m_ObjectSize; ++i) { + if (!m_pObjectState[i]) { + m_pObjectStack[i]->Release(); + } + } + FX_Free(m_pObjectStack); + FX_Free(m_pObjectState); + FX_Free(m_pStreamBuf); + FX_Free(m_pWordBuf); + FX_Free(m_pDictName); +#endif +} +void CPDF_StreamContentParser::PrepareParse(CPDF_Document* pDocument, + CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources, CFX_AffineMatrix* pmtContentToUser, CPDF_PageObjects* pObjList, + CPDF_Dictionary* pResources, CPDF_Rect* pBBox, CPDF_ParseOptions* pOptions, + CPDF_AllStates* pStates, int level) +{ + for (int i = 0; i < 6; i ++) { + m_Type3Data[i] = 0; + } + m_pDocument = pDocument; + m_pPageResources = pPageResources; + m_pParentResources = pParentResources; + if (pmtContentToUser) { + m_mtContentToUser = *pmtContentToUser; + } + if (pOptions) { + m_Options = *pOptions; + } + m_pObjectList = pObjList; + m_pResources = pResources; + if (pResources == NULL) { + m_pResources = m_pParentResources; + } + if (m_pResources == NULL) { + m_pResources = pPageResources; + } + if (pBBox) { + m_BBox = *pBBox; + } + m_Level = level; + m_pCurStates = FX_NEW CPDF_AllStates; + if (pStates) { + m_pCurStates->Copy(*pStates); + } else { + m_pCurStates->m_GeneralState.New(); + m_pCurStates->m_GraphState.New(); + m_pCurStates->m_TextState.New(); + m_pCurStates->m_ColorState.New(); + } +#ifdef _FPDFAPI_MINI_ + FXSYS_memset32(m_pObjectState, 0, _FPDF_MAX_OBJECT_STACK_SIZE_ * sizeof(FX_BOOL)); +#endif +} +int CPDF_StreamContentParser::GetNextParamPos() +{ + if (m_ParamCount == PARAM_BUF_SIZE) { + m_ParamStartPos ++; + if (m_ParamStartPos == PARAM_BUF_SIZE) { + m_ParamStartPos = 0; + } + if (m_ParamBuf1[m_ParamStartPos].m_Type == 0) { + m_ParamBuf1[m_ParamStartPos].m_pObject->Release(); + } + return m_ParamStartPos; + } + int index = m_ParamStartPos + m_ParamCount; + if (index >= PARAM_BUF_SIZE) { + index -= PARAM_BUF_SIZE; + } + m_ParamCount ++; + return index; +} +void CPDF_StreamContentParser::AddNameParam(FX_LPCSTR name, int len) +{ + int index = GetNextParamPos(); + if (len > 32) { + m_ParamBuf1[index].m_Type = 0; + m_ParamBuf1[index].m_pObject = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(name, len))); + } else { + m_ParamBuf1[index].m_Type = PDFOBJ_NAME; + if (FXSYS_memchr(name, '#', len) == NULL) { + FXSYS_memcpy32(m_ParamBuf1[index].m_Name.m_Buffer, name, len); + m_ParamBuf1[index].m_Name.m_Len = len; + } else { + CFX_ByteString str = PDF_NameDecode(CFX_ByteStringC(name, len)); + FXSYS_memcpy32(m_ParamBuf1[index].m_Name.m_Buffer, (FX_LPCSTR)str, str.GetLength()); + m_ParamBuf1[index].m_Name.m_Len = str.GetLength(); + } + } +} +void CPDF_StreamContentParser::AddNumberParam(FX_LPCSTR str, int len) +{ + int index = GetNextParamPos(); + m_ParamBuf1[index].m_Type = PDFOBJ_NUMBER; + FX_atonum(CFX_ByteStringC(str, len), m_ParamBuf1[index].m_Number.m_bInteger, + &m_ParamBuf1[index].m_Number.m_Integer); +} +void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) +{ + int index = GetNextParamPos(); + m_ParamBuf1[index].m_Type = 0; + m_ParamBuf1[index].m_pObject = pObj; +} +void CPDF_StreamContentParser::ClearAllParams() +{ + FX_DWORD index = m_ParamStartPos; + for (FX_DWORD i = 0; i < m_ParamCount; i ++) { + if (m_ParamBuf1[index].m_Type == 0) { + m_ParamBuf1[index].m_pObject->Release(); + } + index ++; + if (index == PARAM_BUF_SIZE) { + index = 0; + } + } + m_ParamStartPos = 0; + m_ParamCount = 0; +} +CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index) +{ + if (index >= m_ParamCount) { + return NULL; + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + _ContentParam& param = m_ParamBuf1[real_index]; + if (param.m_Type == PDFOBJ_NUMBER) { + CPDF_Number* pNumber = CPDF_Number::Create(param.m_Number.m_bInteger, ¶m.m_Number.m_Integer); + param.m_Type = 0; + param.m_pObject = pNumber; + return pNumber; + } + if (param.m_Type == PDFOBJ_NAME) { + CPDF_Name* pName = CPDF_Name::Create(CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len)); + param.m_Type = 0; + param.m_pObject = pName; + return pName; + } + if (param.m_Type == 0) { + return param.m_pObject; + } + ASSERT(FALSE); + return NULL; +} +CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index) +{ + if (index >= m_ParamCount) { + return CFX_ByteString(); + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + _ContentParam& param = m_ParamBuf1[real_index]; + if (param.m_Type == PDFOBJ_NAME) { + return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len); + } + if (param.m_Type == 0) { + return param.m_pObject->GetString(); + } + return CFX_ByteString(); +} +FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index) +{ + if (index >= m_ParamCount) { + return 0; + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + _ContentParam& param = m_ParamBuf1[real_index]; + if (param.m_Type == PDFOBJ_NUMBER) { + return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer : param.m_Number.m_Float; + } + if (param.m_Type == 0) { + return param.m_pObject->GetNumber(); + } + return 0; +} +FX_FLOAT CPDF_StreamContentParser::GetNumber16(FX_DWORD index) +{ + return GetNumber(index); +} +void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph) +{ + pObj->m_GeneralState = m_pCurStates->m_GeneralState; + pObj->m_ClipPath = m_pCurStates->m_ClipPath; + pObj->m_ContentMark = m_CurContentMark; + if (bColor) { + pObj->m_ColorState = m_pCurStates->m_ColorState; + } + if (bGraph) { + pObj->m_GraphState = m_pCurStates->m_GraphState; + } + if (bText) { + pObj->m_TextState = m_pCurStates->m_TextState; + } +} +const struct _OpCode { + FX_DWORD m_OpId; + void (CPDF_StreamContentParser::*m_OpHandler)(); +} g_OpCodes[] = { + {FXBSTR_ID('"', 0, 0, 0), &CPDF_StreamContentParser::Handle_NextLineShowText_Space}, + {FXBSTR_ID('\'', 0, 0, 0), &CPDF_StreamContentParser::Handle_NextLineShowText}, + {FXBSTR_ID('B', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillStrokePath}, + {FXBSTR_ID('B', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillStrokePath}, + {FXBSTR_ID('B', 'D', 'C', 0), &CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary}, + {FXBSTR_ID('B', 'I', 0, 0), &CPDF_StreamContentParser::Handle_BeginImage}, + {FXBSTR_ID('B', 'M', 'C', 0), &CPDF_StreamContentParser::Handle_BeginMarkedContent}, + {FXBSTR_ID('B', 'T', 0, 0), &CPDF_StreamContentParser::Handle_BeginText}, + {FXBSTR_ID('B', 'X', 0, 0), &CPDF_StreamContentParser::Handle_BeginSectionUndefined}, + {FXBSTR_ID('C', 'S', 0, 0), &CPDF_StreamContentParser::Handle_SetColorSpace_Stroke}, + {FXBSTR_ID('D', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace_Dictionary}, + {FXBSTR_ID('D', 'o', 0, 0), &CPDF_StreamContentParser::Handle_ExecuteXObject}, + {FXBSTR_ID('E', 'I', 0, 0), &CPDF_StreamContentParser::Handle_EndImage}, + {FXBSTR_ID('E', 'M', 'C', 0), &CPDF_StreamContentParser::Handle_EndMarkedContent}, + {FXBSTR_ID('E', 'T', 0, 0), &CPDF_StreamContentParser::Handle_EndText}, + {FXBSTR_ID('E', 'X', 0, 0), &CPDF_StreamContentParser::Handle_EndSectionUndefined}, + {FXBSTR_ID('F', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPathOld}, + {FXBSTR_ID('G', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Stroke}, + {FXBSTR_ID('I', 'D', 0, 0), &CPDF_StreamContentParser::Handle_BeginImageData}, + {FXBSTR_ID('J', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineCap}, + {FXBSTR_ID('K', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke}, + {FXBSTR_ID('M', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetMiterLimit}, + {FXBSTR_ID('M', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace}, + {FXBSTR_ID('Q', 0, 0, 0), &CPDF_StreamContentParser::Handle_RestoreGraphState}, + {FXBSTR_ID('R', 'G', 0, 0), &CPDF_StreamContentParser::Handle_SetRGBColor_Stroke}, + {FXBSTR_ID('S', 0, 0, 0), &CPDF_StreamContentParser::Handle_StrokePath}, + {FXBSTR_ID('S', 'C', 0, 0), &CPDF_StreamContentParser::Handle_SetColor_Stroke}, + {FXBSTR_ID('S', 'C', 'N', 0), &CPDF_StreamContentParser::Handle_SetColorPS_Stroke}, + {FXBSTR_ID('T', '*', 0, 0), &CPDF_StreamContentParser::Handle_MoveToNextLine}, + {FXBSTR_ID('T', 'D', 0, 0), &CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading}, + {FXBSTR_ID('T', 'J', 0, 0), &CPDF_StreamContentParser::Handle_ShowText_Positioning}, + {FXBSTR_ID('T', 'L', 0, 0), &CPDF_StreamContentParser::Handle_SetTextLeading}, + {FXBSTR_ID('T', 'c', 0, 0), &CPDF_StreamContentParser::Handle_SetCharSpace}, + {FXBSTR_ID('T', 'd', 0, 0), &CPDF_StreamContentParser::Handle_MoveTextPoint}, + {FXBSTR_ID('T', 'f', 0, 0), &CPDF_StreamContentParser::Handle_SetFont}, + {FXBSTR_ID('T', 'j', 0, 0), &CPDF_StreamContentParser::Handle_ShowText}, + {FXBSTR_ID('T', 'm', 0, 0), &CPDF_StreamContentParser::Handle_SetTextMatrix}, + {FXBSTR_ID('T', 'r', 0, 0), &CPDF_StreamContentParser::Handle_SetTextRenderMode}, + {FXBSTR_ID('T', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetTextRise}, + {FXBSTR_ID('T', 'w', 0, 0), &CPDF_StreamContentParser::Handle_SetWordSpace}, + {FXBSTR_ID('T', 'z', 0, 0), &CPDF_StreamContentParser::Handle_SetHorzScale}, + {FXBSTR_ID('W', 0, 0, 0), &CPDF_StreamContentParser::Handle_Clip}, + {FXBSTR_ID('W', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOClip}, + {FXBSTR_ID('b', 0, 0, 0), &CPDF_StreamContentParser::Handle_CloseFillStrokePath}, + {FXBSTR_ID('b', '*', 0, 0), &CPDF_StreamContentParser::Handle_CloseEOFillStrokePath}, + {FXBSTR_ID('c', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_123}, + {FXBSTR_ID('c', 'm', 0, 0), &CPDF_StreamContentParser::Handle_ConcatMatrix}, + {FXBSTR_ID('c', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetColorSpace_Fill}, + {FXBSTR_ID('d', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetDash}, + {FXBSTR_ID('d', '0', 0, 0), &CPDF_StreamContentParser::Handle_SetCharWidth}, + {FXBSTR_ID('d', '1', 0, 0), &CPDF_StreamContentParser::Handle_SetCachedDevice}, + {FXBSTR_ID('f', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPath}, + {FXBSTR_ID('f', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillPath}, + {FXBSTR_ID('g', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Fill}, + {FXBSTR_ID('g', 's', 0, 0), &CPDF_StreamContentParser::Handle_SetExtendGraphState}, + {FXBSTR_ID('h', 0, 0, 0), &CPDF_StreamContentParser::Handle_ClosePath}, + {FXBSTR_ID('i', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetFlat}, + {FXBSTR_ID('j', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineJoin}, + {FXBSTR_ID('k', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetCMYKColor_Fill}, + {FXBSTR_ID('l', 0, 0, 0), &CPDF_StreamContentParser::Handle_LineTo}, + {FXBSTR_ID('m', 0, 0, 0), &CPDF_StreamContentParser::Handle_MoveTo}, + {FXBSTR_ID('n', 0, 0, 0), &CPDF_StreamContentParser::Handle_EndPath}, + {FXBSTR_ID('q', 0, 0, 0), &CPDF_StreamContentParser::Handle_SaveGraphState}, + {FXBSTR_ID('r', 'e', 0, 0), &CPDF_StreamContentParser::Handle_Rectangle}, + {FXBSTR_ID('r', 'g', 0, 0), &CPDF_StreamContentParser::Handle_SetRGBColor_Fill}, + {FXBSTR_ID('r', 'i', 0, 0), &CPDF_StreamContentParser::Handle_SetRenderIntent}, + {FXBSTR_ID('s', 0, 0, 0), &CPDF_StreamContentParser::Handle_CloseStrokePath}, + {FXBSTR_ID('s', 'c', 0, 0), &CPDF_StreamContentParser::Handle_SetColor_Fill}, + {FXBSTR_ID('s', 'c', 'n', 0), &CPDF_StreamContentParser::Handle_SetColorPS_Fill}, + {FXBSTR_ID('s', 'h', 0, 0), &CPDF_StreamContentParser::Handle_ShadeFill}, + {FXBSTR_ID('v', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_23}, + {FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth}, + {FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13}, +}; +FX_BOOL CPDF_StreamContentParser::OnOperator(FX_LPCSTR op) +{ + int i = 0; + FX_DWORD opid = 0; + while (i < 4 && op[i]) { + opid = (opid << 8) + op[i]; + i ++; + } + while (i < 4) { + opid <<= 8; + i ++; + }; + int low = 0, high = sizeof g_OpCodes / sizeof(struct _OpCode) - 1; + while (low <= high) { + int middle = (low + high) / 2; + int compare = opid - g_OpCodes[middle].m_OpId; + if (compare == 0) { + (this->*g_OpCodes[middle].m_OpHandler)(); + return TRUE; + } else if (compare < 0) { + high = middle - 1; + } else { + low = middle + 1; + } + } + return m_CompatCount != 0; +} +void CPDF_StreamContentParser::Handle_CloseFillStrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + Handle_ClosePath(); + AddPathObject(FXFILL_WINDING, TRUE); +} +void CPDF_StreamContentParser::Handle_FillStrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(FXFILL_WINDING, TRUE); +} +void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); + AddPathObject(FXFILL_ALTERNATE, TRUE); +} +void CPDF_StreamContentParser::Handle_EOFillStrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(FXFILL_ALTERNATE, TRUE); +} +void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() +{ + if (!m_Options.m_bMarkedContent) { + return; + } + CFX_ByteString tag = GetString(1); + CPDF_Object* pProperty = GetObject(0); + if (pProperty == NULL) { + return; + } + FX_BOOL bDirect = TRUE; + if (pProperty->GetType() == PDFOBJ_NAME) { + pProperty = FindResourceObj(FX_BSTRC("Properties"), pProperty->GetString()); + if (pProperty == NULL) { + return; + } + bDirect = FALSE; + } + if (pProperty->GetType() != PDFOBJ_DICTIONARY) { + return; + } + m_CurContentMark.GetModify()->AddMark(tag, (CPDF_Dictionary*)pProperty, bDirect); +} +void CPDF_StreamContentParser::Handle_BeginMarkedContent() +{ + if (!m_Options.m_bMarkedContent) { + return; + } + CFX_ByteString tag = GetString(0); + m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE); +} +struct _FX_BSTR { + FX_LPCSTR m_Ptr; + int m_Size; +}; +#define _FX_BSTRC(str) {str, sizeof(str)-1} +const _FX_BSTR _PDF_InlineKeyAbbr[] = { + _FX_BSTRC("BitsPerComponent"), _FX_BSTRC("BPC"), + _FX_BSTRC("ColorSpace"), _FX_BSTRC("CS"), + _FX_BSTRC("Decode"), _FX_BSTRC("D"), + _FX_BSTRC("DecodeParms"), _FX_BSTRC("DP"), + _FX_BSTRC("Filter"), _FX_BSTRC("F"), + _FX_BSTRC("Height"), _FX_BSTRC("H"), + _FX_BSTRC("ImageMask"), _FX_BSTRC("IM"), + _FX_BSTRC("Interpolate"), _FX_BSTRC("I"), + _FX_BSTRC("Width"), _FX_BSTRC("W"), +}; +const _FX_BSTR _PDF_InlineValueAbbr[] = { + _FX_BSTRC("DeviceGray"), _FX_BSTRC("G"), + _FX_BSTRC("DeviceRGB"), _FX_BSTRC("RGB"), + _FX_BSTRC("DeviceCMYK"), _FX_BSTRC("CMYK"), + _FX_BSTRC("Indexed"), _FX_BSTRC("I"), + _FX_BSTRC("ASCIIHexDecode"), _FX_BSTRC("AHx"), + _FX_BSTRC("ASCII85Decode"), _FX_BSTRC("A85"), + _FX_BSTRC("LZWDecode"), _FX_BSTRC("LZW"), + _FX_BSTRC("FlateDecode"), _FX_BSTRC("Fl"), + _FX_BSTRC("RunLengthDecode"), _FX_BSTRC("RL"), + _FX_BSTRC("CCITTFaxDecode"), _FX_BSTRC("CCF"), + _FX_BSTRC("DCTDecode"), _FX_BSTRC("DCT"), +}; +static CFX_ByteStringC _PDF_FindFullName(const _FX_BSTR* table, int count, FX_BSTR abbr) +{ + int i = 0; + while (i < count) { + if (abbr.GetLength() == table[i + 1].m_Size && FXSYS_memcmp32(abbr.GetPtr(), table[i + 1].m_Ptr, abbr.GetLength()) == 0) { + return CFX_ByteStringC(table[i].m_Ptr, table[i].m_Size); + } + i += 2; + } + return CFX_ByteStringC(); +} +void _PDF_ReplaceAbbr(CPDF_Object* pObj) +{ + switch (pObj->GetType()) { + case PDFOBJ_DICTIONARY: { + CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj; + FX_POSITION pos = pDict->GetStartPos(); + while (pos) { + CFX_ByteString key; + CPDF_Object* value = pDict->GetNextElement(pos, key); + CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineKeyAbbr, + sizeof _PDF_InlineKeyAbbr / sizeof(_FX_BSTR), key); + if (!fullname.IsEmpty()) { + pDict->ReplaceKey(key, fullname); + key = fullname; + } + if (value->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = value->GetString(); + fullname = _PDF_FindFullName(_PDF_InlineValueAbbr, + sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name); + if (!fullname.IsEmpty()) { + pDict->SetAtName(key, fullname); + } + } else { + _PDF_ReplaceAbbr(value); + } + } + break; + } + case PDFOBJ_ARRAY: { + CPDF_Array* pArray = (CPDF_Array*)pObj; + for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { + CPDF_Object* pElement = pArray->GetElement(i); + if (pElement->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = pElement->GetString(); + CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineValueAbbr, + sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name); + if (!fullname.IsEmpty()) { + pArray->SetAt(i, CPDF_Name::Create(fullname)); + } + } else { + _PDF_ReplaceAbbr(pElement); + } + } + break; + } + } +} +static CFX_ByteStringC _PDF_FindAbbrName(const _FX_BSTR* table, int count, FX_BSTR fullName) +{ + int i = 0; + while (i < count) { + if (fullName.GetLength() == table[i].m_Size && FXSYS_memcmp32(fullName.GetPtr(), table[i].m_Ptr, fullName.GetLength()) == 0) { + return CFX_ByteStringC(table[i + 1].m_Ptr, table[i + 1].m_Size); + } + i += 2; + } + return CFX_ByteStringC(); +} +void _PDF_ReplaceFull(CPDF_Object* pObj) +{ + switch (pObj->GetType()) { + case PDFOBJ_DICTIONARY: { + CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj; + FX_POSITION pos = pDict->GetStartPos(); + while (pos) { + CFX_ByteString key; + CPDF_Object* value = pDict->GetNextElement(pos, key); + CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineKeyAbbr, + sizeof(_PDF_InlineKeyAbbr) / sizeof(_FX_BSTR), key); + if (!abbrName.IsEmpty()) { + pDict->ReplaceKey(key, abbrName); + key = abbrName; + } + if (value->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = value->GetString(); + abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr, + sizeof(_PDF_InlineValueAbbr) / sizeof(_FX_BSTR), name); + if (!abbrName.IsEmpty()) { + pDict->SetAtName(key, abbrName); + } + } else { + _PDF_ReplaceFull(value); + } + } + break; + } + case PDFOBJ_ARRAY: { + CPDF_Array* pArray = (CPDF_Array*)pObj; + for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { + CPDF_Object* pElement = pArray->GetElement(i); + if (pElement->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = pElement->GetString(); + CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr, + sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name); + if (!abbrName.IsEmpty()) { + pArray->SetAt(i, CPDF_Name::Create(abbrName)); + } + } else { + _PDF_ReplaceFull(pElement); + } + } + break; + } + } +} +void CPDF_StreamContentParser::Handle_BeginText() +{ + m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); + OnChangeTextMatrix(); + m_pCurStates->m_TextX = 0; + m_pCurStates->m_TextY = 0; + m_pCurStates->m_TextLineX = 0; + m_pCurStates->m_TextLineY = 0; +} +void CPDF_StreamContentParser::Handle_BeginSectionUndefined() +{ + m_CompatCount ++; +} +void CPDF_StreamContentParser::Handle_CurveTo_123() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} +void CPDF_StreamContentParser::Handle_ConcatMatrix() +{ + FX_FLOAT a2 = GetNumber16(5), b2 = GetNumber16(4), c2 = GetNumber16(3), d2 = GetNumber16(2); + FX_FLOAT e2 = GetNumber(1), f2 = GetNumber(0); + FX_FLOAT old_width_scale = m_pCurStates->m_CTM.GetXUnit(); + CFX_AffineMatrix new_matrix(a2, b2, c2, d2, e2, f2); + new_matrix.Concat(m_pCurStates->m_CTM); + m_pCurStates->m_CTM = new_matrix; + FX_FLOAT new_width_scale = m_pCurStates->m_CTM.GetXUnit(); + OnChangeTextMatrix(); +} +void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() +{ + if (m_Options.m_bTextOnly) { + return; + } + CFX_ByteString csname = GetString(0); + CPDF_ColorSpace* pCS = FindColorSpace(csname); + if (pCS == NULL) { + return; + } + m_pCurStates->m_ColorState.GetModify()->m_FillColor.SetColorSpace(pCS); +} +void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() +{ + if (m_Options.m_bTextOnly) { + return; + } + CFX_ByteString csname = GetString(0); + CPDF_ColorSpace* pCS = FindColorSpace(csname); + if (pCS == NULL) { + return; + } + m_pCurStates->m_ColorState.GetModify()->m_StrokeColor.SetColorSpace(pCS); +} +void CPDF_StreamContentParser::Handle_SetDash() +{ + if (m_Options.m_bTextOnly) { + return; + } + CPDF_Array* pArray = GetObject(1)->GetArray(); + if (pArray == NULL) { + return; + } + m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f); +} +void CPDF_StreamContentParser::Handle_SetCharWidth() +{ + m_Type3Data[0] = GetNumber(1); + m_Type3Data[1] = GetNumber(0); + m_bColored = TRUE; +} +void CPDF_StreamContentParser::Handle_SetCachedDevice() +{ + for (int i = 0; i < 6; i ++) { + m_Type3Data[i] = GetNumber(5 - i); + } + m_bColored = FALSE; +} +void CPDF_StreamContentParser::Handle_ExecuteXObject() +{ + CFX_ByteString name = GetString(0); + if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && m_pLastImage->GetStream()->GetObjNum()) { +#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_) + AddDuplicateImage(); +#else + AddImage(NULL, m_pLastImage, FALSE); +#endif + return; + } + if (m_Options.m_bTextOnly) { + CPDF_Object* pRes = NULL; + if (m_pResources == NULL) { + return; + } + if (m_pResources == m_pPageResources) { + CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject")); + if (pList == NULL) { + return; + } + pRes = pList->GetElement(name); + if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) { + return; + } + } else { + CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject")); + if (pList == NULL) { + if (m_pPageResources == NULL) { + return; + } + CPDF_Dictionary* pList = m_pPageResources->GetDict(FX_BSTRC("XObject")); + if (pList == NULL) { + return; + } + pRes = pList->GetElement(name); + if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) { + return; + } + } else { + pRes = pList->GetElement(name); + if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) { + return; + } + } + } + FX_BOOL bForm; + if (m_pDocument->IsFormStream(((CPDF_Reference*)pRes)->GetRefObjNum(), bForm) && !bForm) { + return; + } + } + CPDF_Stream* pXObject = (CPDF_Stream*)FindResourceObj(FX_BSTRC("XObject"), name); + if (pXObject == NULL || pXObject->GetType() != PDFOBJ_STREAM) { + m_bResourceMissing = TRUE; + return; + } + CFX_ByteStringC type = pXObject->GetDict()->GetConstString(FX_BSTRC("Subtype")); + if (type == FX_BSTRC("Image")) { + if (m_Options.m_bTextOnly) { + return; + } + CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE); + m_LastImageName = name; + m_pLastImage = pObj->m_pImage; + } else if (type == FX_BSTRC("Form")) { + AddForm(pXObject); + } else { + return; + } +} +void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) +{ +#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) + if (!m_Options.m_bSeparateForm) { + CPDF_Dictionary* pResources = pStream->GetDict()->GetDict(FX_BSTRC("Resources")); + CFX_AffineMatrix form_matrix = pStream->GetDict()->GetMatrix(FX_BSTRC("Matrix")); + form_matrix.Concat(m_pCurStates->m_CTM); + CPDF_Array* pBBox = pStream->GetDict()->GetArray(FX_BSTRC("BBox")); + CFX_FloatRect form_bbox; + CPDF_Path ClipPath; + if (pBBox) { + form_bbox = pStream->GetDict()->GetRect(FX_BSTRC("BBox")); + ClipPath.New(); + ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top); + ClipPath.Transform(&form_matrix); + form_bbox.Transform(&form_matrix); + } + CPDF_StreamContentParser parser; + parser.Initialize(); + parser.PrepareParse(m_pDocument, m_pPageResources, m_pResources, &m_mtContentToUser, + m_pObjectList, pResources, &form_bbox, &m_Options, m_pCurStates, m_Level + 1); + parser.m_pCurStates->m_CTM = form_matrix; + if (ClipPath.NotNull()) { + parser.m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE); + } + CPDF_StreamAcc stream; + stream.LoadAllData(pStream, FALSE); + if (stream.GetSize() == 0) { + return; + } +#ifdef _FPDFAPI_MINI_ + parser.InputData(stream.GetData(), stream.GetSize()); + parser.Finish(); +#else + parser.Parse(stream.GetData(), stream.GetSize(), 0); +#endif + return; + } +#endif + CPDF_FormObject* pFormObj = FX_NEW CPDF_FormObject; + pFormObj->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources); + pFormObj->m_FormMatrix = m_pCurStates->m_CTM; + pFormObj->m_FormMatrix.Concat(m_mtContentToUser); + CPDF_AllStates status; + status.m_GeneralState = m_pCurStates->m_GeneralState; + status.m_GraphState = m_pCurStates->m_GraphState; + status.m_ColorState = m_pCurStates->m_ColorState; + status.m_TextState = m_pCurStates->m_TextState; + pFormObj->m_pForm->ParseContent(&status, NULL, NULL, &m_Options, m_Level + 1); + if (!m_pObjectList->m_bBackgroundAlphaNeeded && pFormObj->m_pForm->m_bBackgroundAlphaNeeded) { + m_pObjectList->m_bBackgroundAlphaNeeded = TRUE; + } + pFormObj->CalcBoundingBox(); + SetGraphicStates(pFormObj, TRUE, TRUE, TRUE); + m_pObjectList->m_ObjectList.AddTail(pFormObj); +} +#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_) +void CPDF_StreamContentParser::AddDuplicateImage() +{ + FX_POSITION tailpos = m_pObjectList->m_ObjectList.GetTailPosition(); + CPDF_PageObject* pLastObj = (CPDF_PageObject*)m_pObjectList->m_ObjectList.GetAt(tailpos); + if (pLastObj == NULL || (pLastObj->m_Type != PDFPAGE_INLINES && pLastObj->m_Type != PDFPAGE_IMAGE)) { + AddImage(NULL, m_pLastImage, FALSE); + return; + } + if (pLastObj->m_GeneralState != m_pCurStates->m_GeneralState || + pLastObj->m_ClipPath != m_pCurStates->m_ClipPath || + pLastObj->m_ColorState != m_pCurStates->m_ColorState) { + AddImage(NULL, m_pLastImage, FALSE); + return; + } + CFX_AffineMatrix ImageMatrix; + ImageMatrix.Copy(m_pCurStates->m_CTM); + ImageMatrix.Concat(m_mtContentToUser); + if (pLastObj->m_Type == PDFPAGE_INLINES) { + CPDF_InlineImages* pInlines = (CPDF_InlineImages*)pLastObj; + if (pInlines->m_pStream != m_pLastImage->GetStream()) { + AddImage(NULL, m_pLastImage, FALSE); + return; + } + pInlines->AddMatrix(ImageMatrix); + } else { + CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pLastObj; + CPDF_InlineImages* pInlines = FX_NEW CPDF_InlineImages; + pInlines->m_pStream = m_pLastImage->GetStream(); + SetGraphicStates(pInlines, !pInlines->m_pStream->GetDict()->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE); + pInlines->AddMatrix(pImageObj->m_Matrix); + pInlines->AddMatrix(ImageMatrix); + m_pObjectList->m_ObjectList.RemoveAt(tailpos); + m_pObjectList->m_ObjectList.AddTail(pInlines); + pLastObj->Release(); + } +} +#endif +CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, CPDF_Image* pImage, FX_BOOL bInline) +{ + if (pStream == NULL && pImage == NULL) { + return NULL; + } + CFX_AffineMatrix ImageMatrix; + ImageMatrix.Copy(m_pCurStates->m_CTM); + ImageMatrix.Concat(m_mtContentToUser); + CPDF_ImageObject* pImageObj = FX_NEW CPDF_ImageObject; + if (pImage) { + pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pImage->GetStream()); + } else if (pStream->GetObjNum()) { + pImageObj->m_pImage = m_pDocument->LoadImageF(pStream); + } else { + pImageObj->m_pImage = FX_NEW CPDF_Image(m_pDocument); + pImageObj->m_pImage->LoadImageF(pStream, bInline); + } + SetGraphicStates(pImageObj, pImageObj->m_pImage->IsMask(), FALSE, FALSE); + pImageObj->m_Matrix = ImageMatrix; + pImageObj->CalcBoundingBox(); + m_pObjectList->m_ObjectList.AddTail(pImageObj); + return pImageObj; +} +void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() +{ +} +void CPDF_StreamContentParser::Handle_EndImage() +{ +} +void CPDF_StreamContentParser::Handle_EndMarkedContent() +{ + if (!m_Options.m_bMarkedContent) { + return; + } + if (m_CurContentMark.IsNull()) { + return; + } + int count = m_CurContentMark.GetObject()->CountItems(); + if (count == 1) { + m_CurContentMark.SetNull(); + return; + } + m_CurContentMark.GetModify()->DeleteLastMark(); +} +void CPDF_StreamContentParser::Handle_EndText() +{ + int count = m_ClipTextList.GetSize(); + if (count == 0) { + return; + } + if (m_pCurStates->m_TextState.GetObject()->m_TextMode < 4) { + for (int i = 0; i < count; i ++) { + CPDF_TextObject* pText = (CPDF_TextObject*)m_ClipTextList.GetAt(i); + if (pText) { + delete pText; + } + } + } else { + m_pCurStates->m_ClipPath.AppendTexts((CPDF_TextObject**)m_ClipTextList.GetData(), count); + } + m_ClipTextList.RemoveAll(); +} +void CPDF_StreamContentParser::Handle_EndSectionUndefined() +{ + if (m_CompatCount) { + m_CompatCount --; + } +} +void CPDF_StreamContentParser::Handle_FillPath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(FXFILL_WINDING, FALSE); +} +void CPDF_StreamContentParser::Handle_FillPathOld() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(FXFILL_WINDING, FALSE); +} +void CPDF_StreamContentParser::Handle_EOFillPath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(FXFILL_ALTERNATE, FALSE); +} +void CPDF_StreamContentParser::Handle_SetGray_Fill() +{ + FX_FLOAT value = GetNumber(0); + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1); +} +void CPDF_StreamContentParser::Handle_SetGray_Stroke() +{ + FX_FLOAT value = GetNumber(0); + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1); +} +void CPDF_StreamContentParser::Handle_SetExtendGraphState() +{ + CFX_ByteString name = GetString(0); + CPDF_Dictionary* pGS = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("ExtGState"), name); + if (pGS == NULL || pGS->GetType() != PDFOBJ_DICTIONARY) { + m_bResourceMissing = TRUE; + return; + } + m_pCurStates->ProcessExtGS(pGS, this); +} +void CPDF_StreamContentParser::Handle_ClosePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + if (m_PathPointCount == 0) { + return; + } + if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) { + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); + } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) { + m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; + } +} +void CPDF_StreamContentParser::Handle_SetFlat() +{ +#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) + m_pCurStates->m_GeneralState.GetModify()->m_Flatness = GetNumber(0); +#endif +} +void CPDF_StreamContentParser::Handle_BeginImageData() +{ +} +void CPDF_StreamContentParser::Handle_SetLineJoin() +{ + m_pCurStates->m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)GetInteger(0); +} +void CPDF_StreamContentParser::Handle_SetLineCap() +{ + m_pCurStates->m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)GetInteger(0); +} +void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() +{ + REQUIRE_PARAMS(4); + FX_FLOAT values[4]; + for (int i = 0; i < 4; i ++) { + values[i] = GetNumber(3 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4); +} +void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() +{ + REQUIRE_PARAMS(4); + FX_FLOAT values[4]; + for (int i = 0; i < 4; i ++) { + values[i] = GetNumber(3 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4); +} +void CPDF_StreamContentParser::Handle_LineTo() +{ + REQUIRE_PARAMS(2); + if (m_Options.m_bTextOnly) { + return; + } + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO); +} +void CPDF_StreamContentParser::Handle_MoveTo() +{ + REQUIRE_PARAMS(2); + if (m_Options.m_bTextOnly) { +#ifndef _FPDFAPI_MINI_ + m_pSyntax->SkipPathObject(); +#endif + return; + } + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO); +#ifndef _FPDFAPI_MINI_ + ParsePathObject(); +#endif +} +void CPDF_StreamContentParser::Handle_SetMiterLimit() +{ + m_pCurStates->m_GraphState.GetModify()->m_MiterLimit = GetNumber(0); +} +void CPDF_StreamContentParser::Handle_MarkPlace() +{ +} +void CPDF_StreamContentParser::Handle_EndPath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(0, FALSE); +} +void CPDF_StreamContentParser::Handle_SaveGraphState() +{ + CPDF_AllStates* pStates = FX_NEW CPDF_AllStates; + pStates->Copy(*m_pCurStates); + m_StateStack.Add(pStates); +} +void CPDF_StreamContentParser::Handle_RestoreGraphState() +{ + int size = m_StateStack.GetSize(); + if (size == 0) { + return; + } + CPDF_AllStates* pStates = (CPDF_AllStates*)m_StateStack.GetAt(size - 1); + m_pCurStates->Copy(*pStates); + delete pStates; + m_StateStack.RemoveAt(size - 1); +} +void CPDF_StreamContentParser::Handle_Rectangle() +{ + if (m_Options.m_bTextOnly) { + return; + } + FX_FLOAT x = GetNumber(3), y = GetNumber(2); + FX_FLOAT w = GetNumber(1), h = GetNumber(0); + AddPathRect(x, y, w, h); +} +void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h) +{ + AddPathPoint(x, y, FXPT_MOVETO); + AddPathPoint(x + w, y, FXPT_LINETO); + AddPathPoint(x + w, y + h, FXPT_LINETO); + AddPathPoint(x, y + h, FXPT_LINETO); + AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE); +} +void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() +{ + REQUIRE_PARAMS(3); + FX_FLOAT values[3]; + for (int i = 0; i < 3; i ++) { + values[i] = GetNumber(2 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3); +} +void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() +{ + REQUIRE_PARAMS(3); + FX_FLOAT values[3]; + for (int i = 0; i < 3; i ++) { + values[i] = GetNumber(2 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3); +} +void CPDF_StreamContentParser::Handle_SetRenderIntent() +{ +} +void CPDF_StreamContentParser::Handle_CloseStrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + Handle_ClosePath(); + AddPathObject(0, TRUE); +} +void CPDF_StreamContentParser::Handle_StrokePath() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathObject(0, TRUE); +} +void CPDF_StreamContentParser::Handle_SetColor_Fill() +{ + if (m_Options.m_bTextOnly) { + return; + } + FX_FLOAT values[4]; + int nargs = m_ParamCount; + if (nargs > 4) { + nargs = 4; + } + for (int i = 0; i < nargs; i ++) { + values[i] = GetNumber(nargs - i - 1); + } + m_pCurStates->m_ColorState.SetFillColor(NULL, values, nargs); +} +void CPDF_StreamContentParser::Handle_SetColor_Stroke() +{ + if (m_Options.m_bTextOnly) { + return; + } + FX_FLOAT values[4]; + int nargs = m_ParamCount; + if (nargs > 4) { + nargs = 4; + } + for (int i = 0; i < nargs; i ++) { + values[i] = GetNumber(nargs - i - 1); + } + m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nargs); +} +void CPDF_StreamContentParser::Handle_SetColorPS_Fill() +{ + if (m_Options.m_bTextOnly) { + return; + } + CPDF_Object* pLastParam = GetObject(0); + if (pLastParam == NULL) { + return; + } + int nargs = m_ParamCount; + int nvalues = nargs; + if (pLastParam->GetType() == PDFOBJ_NAME) { + nvalues --; + } + FX_FLOAT* values = NULL; + if (nvalues) { + values = FX_Alloc(FX_FLOAT, nvalues); + for (int i = 0; i < nvalues; i ++) { + values[i] = GetNumber(nargs - i - 1); + } + } + if (nvalues != nargs) { + CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); + if (pPattern) { + m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); + } + } else { + m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues); + } + if (values) { + FX_Free(values); + } +} +void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() +{ + if (m_Options.m_bTextOnly) { + return; + } + CPDF_Object* pLastParam = GetObject(0); + if (pLastParam == NULL) { + return; + } + int nargs = m_ParamCount; + int nvalues = nargs; + if (pLastParam->GetType() == PDFOBJ_NAME) { + nvalues --; + } + FX_FLOAT* values = NULL; + if (nvalues) { + values = FX_Alloc(FX_FLOAT, nvalues); + for (int i = 0; i < nvalues; i ++) { + values[i] = GetNumber(nargs - i - 1); + } + } + if (nvalues != nargs) { + CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); + if (pPattern) { + m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); + } + } else { + m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues); + } + if (values) { + FX_Free(values); + } +} +CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix, + CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS); +void CPDF_StreamContentParser::Handle_ShadeFill() +{ + if (m_Options.m_bTextOnly) { + return; + } + CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE); + if (pPattern == NULL) { + return; + } + if (pPattern->m_PatternType != PATTERN_SHADING) { + return; + } + CPDF_ShadingPattern* pShading = (CPDF_ShadingPattern*)pPattern; + if (!pShading->m_bShadingObj) { + return; + } + if (!pShading->Load()) { + return; + } + CPDF_ShadingObject* pObj = FX_NEW CPDF_ShadingObject; + pObj->m_pShading = pShading; + SetGraphicStates(pObj, FALSE, FALSE, FALSE); + pObj->m_Matrix = m_pCurStates->m_CTM; + pObj->m_Matrix.Concat(m_mtContentToUser); + CFX_FloatRect bbox; + if (!pObj->m_ClipPath.IsNull()) { + bbox = pObj->m_ClipPath.GetClipBox(); + } else { + bbox = m_BBox; + } + if (pShading->m_ShadingType >= 4) { + bbox.Intersect(_GetShadingBBox((CPDF_Stream*)pShading->m_pShadingObj, pShading->m_ShadingType, &pObj->m_Matrix, + pShading->m_pFunctions, pShading->m_nFuncs, pShading->m_pCS)); + } + pObj->m_Left = bbox.left; + pObj->m_Right = bbox.right; + pObj->m_Top = bbox.top; + pObj->m_Bottom = bbox.bottom; + m_pObjectList->m_ObjectList.AddTail(pObj); +} +void CPDF_StreamContentParser::Handle_SetCharSpace() +{ + m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0); +} +void CPDF_StreamContentParser::Handle_MoveTextPoint() +{ + m_pCurStates->m_TextLineX += GetNumber(1); + m_pCurStates->m_TextLineY += GetNumber(0); + m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; + m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; +} +void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() +{ + Handle_MoveTextPoint(); + m_pCurStates->m_TextLeading = -GetNumber(0); +} +void CPDF_StreamContentParser::Handle_SetFont() +{ + FX_FLOAT fs = GetNumber(0); + if (fs == 0) { + fs = m_DefFontSize; + } + m_pCurStates->m_TextState.GetModify()->m_FontSize = fs; + CPDF_Font* pFont = FindFont(GetString(1)); + if (pFont) { + m_pCurStates->m_TextState.SetFont(pFont); + } +} +CPDF_Object* CPDF_StreamContentParser::FindResourceObj(FX_BSTR type, const CFX_ByteString& name) +{ + if (m_pResources == NULL) { + return NULL; + } + if (m_pResources == m_pPageResources) { + CPDF_Dictionary* pList = m_pResources->GetDict(type); + if (pList == NULL) { + return NULL; + } + CPDF_Object* pRes = pList->GetElementValue(name); + return pRes; + } + CPDF_Dictionary* pList = m_pResources->GetDict(type); + if (pList == NULL) { + if (m_pPageResources == NULL) { + return NULL; + } + CPDF_Dictionary* pList = m_pPageResources->GetDict(type); + if (pList == NULL) { + return NULL; + } + CPDF_Object* pRes = pList->GetElementValue(name); + return pRes; + } + CPDF_Object* pRes = pList->GetElementValue(name); + return pRes; +} +CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) +{ + CPDF_Dictionary* pFontDict = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("Font"), name); + if (pFontDict == NULL || pFontDict->GetType() != PDFOBJ_DICTIONARY) { + m_bResourceMissing = TRUE; + return CPDF_Font::GetStockFont(m_pDocument, FX_BSTRC("Helvetica")); + } + CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict); + if (pFont && pFont->GetType3Font()) { + pFont->GetType3Font()->SetPageResources(m_pResources); + pFont->GetType3Font()->CheckType3FontMetrics(); + } + return pFont; +} +CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace(const CFX_ByteString& name) +{ + if (name == FX_BSTRC("Pattern")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + } + if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("DeviceRGB")) { + CFX_ByteString defname = "Default"; + defname += name.Mid(7); + CPDF_Object* pDefObj = FindResourceObj(FX_BSTRC("ColorSpace"), defname); + if (pDefObj == NULL) { + if (name == FX_BSTRC("DeviceGray")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + } + if (name == FX_BSTRC("DeviceRGB")) { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + } + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + } + return m_pDocument->LoadColorSpace(pDefObj); + } + CPDF_Object* pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); + if (pCSObj == NULL) { + m_bResourceMissing = TRUE; + return NULL; + } + return m_pDocument->LoadColorSpace(pCSObj); +} +CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, FX_BOOL bShading) +{ + CPDF_Object* pPattern = FindResourceObj(bShading ? FX_BSTRC("Shading") : FX_BSTRC("Pattern"), name); + if (pPattern == NULL || (pPattern->GetType() != PDFOBJ_DICTIONARY && + pPattern->GetType() != PDFOBJ_STREAM)) { + m_bResourceMissing = TRUE; + return NULL; + } + return m_pDocument->LoadPattern(pPattern, bShading, &m_pCurStates->m_ParentMatrix); +} +void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) +{ + m_pCurStates->m_TextMatrix.Transform(x, y, x, y); + ConvertUserSpace(x, y); +} +void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) +{ + m_pCurStates->m_CTM.Transform(x, y, x, y); + m_mtContentToUser.Transform(x, y, x, y); +} +void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int nsegs) +{ + CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont(); + if (pFont == NULL) { + return; + } + if (fInitKerning != 0) { + if (!pFont->IsVertWriting()) { + m_pCurStates->m_TextX -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000; + } else { + m_pCurStates->m_TextY -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000; + } + } + if (nsegs == 0) { + return; + } + int textmode; + if (pFont->GetFontType() == PDFFONT_TYPE3) { + textmode = 0; + } else { + textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode; + } + CPDF_TextObject* pText = FX_NEW CPDF_TextObject; + m_pLastTextObject = pText; + SetGraphicStates(pText, TRUE, TRUE, TRUE); + if (textmode && textmode != 3 && textmode != 4 && textmode != 7) { + FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM; + pCTM[0] = m_pCurStates->m_CTM.a; + pCTM[1] = m_pCurStates->m_CTM.c; + pCTM[2] = m_pCurStates->m_CTM.b; + pCTM[3] = m_pCurStates->m_CTM.d; + } + pText->SetSegments(pStrs, pKerning, nsegs); + pText->m_PosX = m_pCurStates->m_TextX; + pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise; + ConvertTextSpace(pText->m_PosX, pText->m_PosY); + FX_FLOAT x_advance, y_advance; + pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale, m_Level); + m_pCurStates->m_TextX += x_advance; + m_pCurStates->m_TextY += y_advance; + if (textmode > 3) { + CPDF_TextObject* pCopy = FX_NEW CPDF_TextObject; + pCopy->Copy(pText); + m_ClipTextList.Add(pCopy); + } + m_pObjectList->m_ObjectList.AddTail(pText); + if (pKerning && pKerning[nsegs - 1] != 0) { + if (!pFont->IsVertWriting()) { + m_pCurStates->m_TextX -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000; + } else { + m_pCurStates->m_TextY -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000; + } + } +} +void CPDF_StreamContentParser::Handle_ShowText() +{ + CFX_ByteString str = GetString(0); + if (str.IsEmpty()) { + return; + } + AddTextObject(&str, 0, NULL, 1); +} +void CPDF_StreamContentParser::Handle_ShowText_Positioning() +{ + CPDF_Array* pArray = GetObject(0)->GetArray(); + if (pArray == NULL) { + return; + } + int n = pArray->GetCount(), nsegs = 0, i; + for (i = 0; i < n; i ++) { + CPDF_Object* pObj = pArray->GetElementValue(i); + if (pObj->GetType() == PDFOBJ_STRING) { + nsegs ++; + } + } + if (nsegs == 0) { + for (i = 0; i < n; i ++) { + m_pCurStates->m_TextX -= FXSYS_Mul(pArray->GetNumber(i), m_pCurStates->m_TextState.GetFontSize()) / 1000; + }; + return; + } + CFX_ByteString* pStrs; + FX_NEW_VECTOR(pStrs, CFX_ByteString, nsegs); + FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs); + int iSegment = 0; + FX_FLOAT fInitKerning = 0; + for (i = 0; i < n; i ++) { + CPDF_Object* pObj = pArray->GetElementValue(i); + if (pObj->GetType() == PDFOBJ_STRING) { + CFX_ByteString str = pObj->GetString(); + if (str.IsEmpty()) { + continue; + } + pStrs[iSegment] = str; + pKerning[iSegment ++] = 0; + } else { + if (iSegment == 0) { + fInitKerning += pObj->GetNumber(); + } else { + pKerning[iSegment - 1] += pObj->GetNumber(); + } + } + } + AddTextObject(pStrs, fInitKerning, pKerning, iSegment); + FX_DELETE_VECTOR(pStrs, CFX_ByteString, nsegs); + FX_Free(pKerning); +} +void CPDF_StreamContentParser::Handle_SetTextLeading() +{ + m_pCurStates->m_TextLeading = GetNumber(0); +} +void CPDF_StreamContentParser::Handle_SetTextMatrix() +{ + m_pCurStates->m_TextMatrix.Set(GetNumber16(5), GetNumber16(4), GetNumber16(3), + GetNumber16(2), GetNumber(1), GetNumber(0)); + OnChangeTextMatrix(); + m_pCurStates->m_TextX = 0; + m_pCurStates->m_TextY = 0; + m_pCurStates->m_TextLineX = 0; + m_pCurStates->m_TextLineY = 0; +} +void CPDF_StreamContentParser::OnChangeTextMatrix() +{ + CFX_AffineMatrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + text_matrix.Concat(m_pCurStates->m_TextMatrix); + text_matrix.Concat(m_pCurStates->m_CTM); + text_matrix.Concat(m_mtContentToUser); + FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetModify()->m_Matrix; + pTextMatrix[0] = text_matrix.a; + pTextMatrix[1] = text_matrix.c; + pTextMatrix[2] = text_matrix.b; + pTextMatrix[3] = text_matrix.d; +} +void CPDF_StreamContentParser::Handle_SetTextRenderMode() +{ + int mode = GetInteger(0); + if (mode < 0 || mode > 7) { + return; + } + m_pCurStates->m_TextState.GetModify()->m_TextMode = mode; +} +void CPDF_StreamContentParser::Handle_SetTextRise() +{ + m_pCurStates->m_TextRise = GetNumber(0); +} +void CPDF_StreamContentParser::Handle_SetWordSpace() +{ + m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(0); +} +void CPDF_StreamContentParser::Handle_SetHorzScale() +{ + if (m_ParamCount != 1) { + return; + } + m_pCurStates->m_TextHorzScale = GetNumber(0) / 100; + OnChangeTextMatrix(); +} +void CPDF_StreamContentParser::Handle_MoveToNextLine() +{ + m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading; + m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; + m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; +} +void CPDF_StreamContentParser::Handle_CurveTo_23() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} +void CPDF_StreamContentParser::Handle_SetLineWidth() +{ + FX_FLOAT width = GetNumber(0); + m_pCurStates->m_GraphState.GetModify()->m_LineWidth = width; +} +void CPDF_StreamContentParser::Handle_Clip() +{ + m_PathClipType = FXFILL_WINDING; +} +void CPDF_StreamContentParser::Handle_EOClip() +{ + m_PathClipType = FXFILL_ALTERNATE; +} +void CPDF_StreamContentParser::Handle_CurveTo_13() +{ + if (m_Options.m_bTextOnly) { + return; + } + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} +void CPDF_StreamContentParser::Handle_NextLineShowText() +{ + Handle_MoveToNextLine(); + Handle_ShowText(); +} +void CPDF_StreamContentParser::Handle_NextLineShowText_Space() +{ + m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(2); + m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(1); + Handle_NextLineShowText(); +} +void CPDF_StreamContentParser::Handle_Invalid() +{ +} +void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) +{ + m_PathCurrentX = x; + m_PathCurrentY = y; + if (flag == FXPT_MOVETO) { + m_PathStartX = x; + m_PathStartY = y; + if (m_PathPointCount && m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) { + m_pPathPoints[m_PathPointCount - 1].m_PointX = x; + m_pPathPoints[m_PathPointCount - 1].m_PointY = y; + return; + } + } else if (m_PathPointCount == 0) { + return; + } + m_PathPointCount ++; + if (m_PathPointCount > m_PathAllocSize) { + int newsize = m_PathPointCount + 256; + FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize); + if (m_PathAllocSize) { + FXSYS_memcpy32(pNewPoints, m_pPathPoints, m_PathAllocSize * sizeof(FX_PATHPOINT)); + FX_Free(m_pPathPoints); + } + m_pPathPoints = pNewPoints; + m_PathAllocSize = newsize; + } + m_pPathPoints[m_PathPointCount - 1].m_Flag = flag; + m_pPathPoints[m_PathPointCount - 1].m_PointX = x; + m_pPathPoints[m_PathPointCount - 1].m_PointY = y; +} +void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) +{ + int PathPointCount = m_PathPointCount, PathClipType = m_PathClipType; + m_PathPointCount = 0; + m_PathClipType = 0; + if (PathPointCount <= 1) { + if (PathPointCount && PathClipType) { + CPDF_Path path; + path.New()->AppendRect(0, 0, 0, 0); + m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE); + } + return; + } + if (PathPointCount && m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) { + PathPointCount --; + } + CPDF_Path Path; + CFX_PathData* pPathData = Path.New(); + pPathData->SetPointCount(PathPointCount); + FXSYS_memcpy32(pPathData->GetPoints(), m_pPathPoints, sizeof(FX_PATHPOINT) * PathPointCount); + CFX_AffineMatrix matrix = m_pCurStates->m_CTM; + matrix.Concat(m_mtContentToUser); + if (bStroke || FillType) { + CPDF_PathObject* pPathObj = FX_NEW CPDF_PathObject; + pPathObj->m_bStroke = bStroke; + pPathObj->m_FillType = FillType; + pPathObj->m_Path = Path; + pPathObj->m_Matrix = matrix; + SetGraphicStates(pPathObj, TRUE, FALSE, TRUE); + pPathObj->CalcBoundingBox(); + m_pObjectList->m_ObjectList.AddTail(pPathObj); + } + if (PathClipType) { + if (!matrix.IsIdentity()) { + Path.Transform(&matrix); + matrix.SetIdentity(); + } + m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE); + } +} +CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf) +{ + CFX_ByteTextBuf buf; + FX_BOOL bFirst = TRUE; + int code = 0; + FX_LPCBYTE str = src_buf.GetBuffer(); + FX_DWORD size = src_buf.GetSize(); + for (FX_DWORD i = 0; i < size; i ++) { + FX_BYTE ch = str[i]; + if (ch >= '0' && ch <= '9') { + if (bFirst) { + code = (ch - '0') * 16; + } else { + code += ch - '0'; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } else if (ch >= 'A' && ch <= 'F') { + if (bFirst) { + code = (ch - 'A' + 10) * 16; + } else { + code += ch - 'A' + 10; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } else if (ch >= 'a' && ch <= 'f') { + if (bFirst) { + code = (ch - 'a' + 10) * 16; + } else { + code += ch - 'a' + 10; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } + } + if (!bFirst) { + buf.AppendChar((char)code); + } + return buf.GetByteString(); +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_new.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_new.cpp index 2eeb1feff5..5442f9b4ec 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_new.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_new.cpp @@ -1,822 +1,822 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "pageint.h"
-#if defined(_FPDFAPI_MINI_)
-extern const FX_LPCSTR _PDF_CharType;
-void CPDF_StreamContentParser::InputData(FX_LPCBYTE src_buf, FX_DWORD src_size)
-{
- if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
- return;
- }
- for (FX_DWORD i = 0; i < src_size; i ++) {
- int ch = src_buf[i];
- int type = _PDF_CharType[ch];
-start:
- switch (m_WordState) {
- case 0:
- if (type == 'W') {
- } else if (type == 'N') {
- m_WordState = 5;
- m_pWordBuf[0] = ch;
- m_WordSize = 1;
- } else if (type == 'R') {
- m_WordState = 4;
- m_pWordBuf[0] = ch;
- m_WordSize = 1;
- } else switch (ch) {
- case '/':
- m_WordState = 2;
- m_WordSize = 0;
- break;
- case '[':
- StartArray();
- break;
- case ']':
- EndArray();
- break;
- case '(':
- m_WordState = 7;
- m_StringLevel = 1;
- m_StringState = 0;
- m_StringBuf.Clear();
- break;
- case '<':
- m_WordState = 3;
- break;
- case '>':
- m_WordState = 8;
- break;
- case '%':
- m_WordState = 1;
- break;
- }
- break;
- case 1:
- if (ch == '\n' || ch == '\r') {
- m_WordState = 0;
- }
- break;
- case 2:
- if (type != 'R' && type != 'N') {
- EndName();
- m_WordState = 0;
- goto start;
- }
- if (m_WordSize < 256) {
- m_pWordBuf[m_WordSize++] = ch;
- }
- break;
- case 3:
- if (ch == '<') {
- StartDict();
- m_WordState = 0;
- } else {
- m_StringBuf.Clear();
- m_WordState = 6;
- goto start;
- }
- break;
- case 4:
- if (type != 'R' && type != 'N') {
- m_WordState = 0;
- EndKeyword();
- if (m_bAbort) {
- return;
- }
- goto start;
- }
- if (m_WordSize < 256) {
- m_pWordBuf[m_WordSize++] = ch;
- }
- break;
- case 5:
- if (type != 'N') {
- EndNumber();
- m_WordState = 0;
- goto start;
- }
- if (m_WordSize < 256) {
- m_pWordBuf[m_WordSize++] = ch;
- }
- break;
- case 6:
- if (ch == '>') {
- EndHexString();
- m_WordState = 0;
- } else {
- m_StringBuf.AppendByte(ch);
- }
- break;
- case 7:
- switch (m_StringState) {
- case 0:
- if (ch == ')') {
- m_StringLevel --;
- if (m_StringLevel == 0) {
- EndString();
- m_WordState = 0;
- break;
- }
- m_StringBuf.AppendByte(')');
- } else if (ch == '(') {
- m_StringLevel ++;
- m_StringBuf.AppendByte('(');
- } else if (ch == '\\') {
- m_StringState = 1;
- } else {
- m_StringBuf.AppendByte((char)ch);
- }
- break;
- case 1:
- if (ch >= '0' && ch <= '7') {
- m_EscCode = ch - '0';
- m_StringState = 2;
- break;
- }
- if (ch == 'n') {
- m_StringBuf.AppendByte('\n');
- } else if (ch == 'r') {
- m_StringBuf.AppendByte('\r');
- } else if (ch == 't') {
- m_StringBuf.AppendByte('\t');
- } else if (ch == 'b') {
- m_StringBuf.AppendByte('\b');
- } else if (ch == 'f') {
- m_StringBuf.AppendByte('\f');
- } else if (ch == '\\') {
- m_StringBuf.AppendByte('\\');
- } else if (ch == '(') {
- m_StringBuf.AppendByte('(');
- } else if (ch == ')') {
- m_StringBuf.AppendByte(')');
- } else if (ch == '\r') {
- m_StringState = 4;
- break;
- } else if (ch == '\n') {
- } else {
- m_StringBuf.AppendByte(ch);
- }
- m_StringState = 0;
- break;
- case 2:
- if (ch >= '0' && ch <= '7') {
- m_EscCode = m_EscCode * 8 + ch - '0';
- m_StringState = 3;
- } else {
- m_StringBuf.AppendByte(m_EscCode);
- m_StringState = 0;
- goto start;
- }
- break;
- case 3:
- if (ch >= '0' && ch <= '7') {
- m_EscCode = m_EscCode * 8 + ch - '0';
- m_StringBuf.AppendByte(m_EscCode);
- m_StringState = 0;
- } else {
- m_StringBuf.AppendByte(m_EscCode);
- m_StringState = 0;
- goto start;
- }
- break;
- case 4:
- m_StringState = 0;
- if (ch != '\n') {
- goto start;
- }
- break;
- }
- break;
- case 8:
- m_WordState = 0;
- if (ch == '>') {
- EndDict();
- } else {
- goto start;
- }
- break;
- case 9:
- switch (m_InlineImageState) {
- case 0:
- if (type == 'W' || type == 'D') {
- m_InlineImageState = 1;
- m_InlineWhiteChar = ch;
- } else {
- m_StringBuf.AppendByte(ch);
- }
- break;
- case 1:
- m_StringBuf.AppendByte(m_InlineWhiteChar);
- if (ch == 'I') {
- m_InlineImageState = 2;
- } else {
- m_InlineImageState = 0;
- goto start;
- }
- break;
- case 2:
- if (ch == 'D') {
- m_InlineImageState = 3;
- } else {
- m_StringBuf.AppendByte('I');
- m_InlineImageState = 0;
- goto start;
- }
- break;
- case 3:
- EndImageDict();
- break;
- }
- break;
- case 10:
- switch (m_InlineImageState) {
- case 0:
- if (type == 'W') {
- m_InlineImageState = 1;
- m_InlineWhiteChar = ch;
- } else {
- m_ImageSrcBuf.AppendByte(ch);
- }
- break;
- case 1:
- if (ch == 'E') {
- m_InlineImageState = 2;
- } else {
- m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
- m_InlineImageState = 0;
- goto start;
- }
- break;
- case 2:
- if (ch == 'I') {
- m_InlineImageState = 3;
- } else {
- m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
- m_ImageSrcBuf.AppendByte('E');
- m_InlineImageState = 0;
- goto start;
- }
- break;
- case 3:
- if (type == 'W') {
- EndInlineImage();
- } else {
- m_ImageSrcBuf.AppendByte(m_InlineWhiteChar);
- m_ImageSrcBuf.AppendByte('E');
- m_ImageSrcBuf.AppendByte('I');
- m_InlineImageState = 0;
- goto start;
- }
- break;
- }
- break;
- case 11:
- if (m_InlineImageState < m_ImageSrcBuf.GetSize()) {
- m_ImageSrcBuf.GetBuffer()[m_InlineImageState ++] = ch;
- } else {
- if (ch == 'I') {
- EndInlineImage();
- }
- }
- break;
- }
- }
-}
-void CPDF_StreamContentParser::Finish()
-{
- switch (m_WordState) {
- case 0:
- break;
- case 1:
- break;
- case 2:
- EndName();
- break;
- case 3:
- break;
- case 4:
- EndKeyword();
- break;
- case 5:
- EndNumber();
- break;
- case 6:
- EndHexString();
- break;
- case 7:
- EndString();
- break;
- case 8:
- break;
- case 9:
- break;
- case 10:
- EndInlineImage();
- break;
- }
- m_WordState = 0;
-}
-void CPDF_StreamContentParser::AddContainer(CPDF_Object* pObject)
-{
- if (m_ObjectSize) {
- m_pObjectState[m_ObjectSize] = SetToCurObj(pObject);
- }
- FXSYS_assert(m_ObjectSize < _FPDF_MAX_OBJECT_STACK_SIZE_);
- m_pObjectStack[m_ObjectSize++] = pObject;
-}
-FX_BOOL CPDF_StreamContentParser::SetToCurObj(CPDF_Object* pObject)
-{
- if (m_ObjectSize == 0) {
- AddObjectParam(pObject);
- return TRUE;
- }
- FX_BOOL bInArrayOrDict = TRUE;
- CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
- if (pCurObj->GetType() == PDFOBJ_ARRAY) {
- ((CPDF_Array*)pCurObj)->Add(pObject, m_pDocument);
- } else {
- if (!m_bDictName && m_pDictName[0]) {
- ((CPDF_Dictionary*)pCurObj)->SetAt((FX_LPCSTR)m_pDictName, pObject, m_pDocument);
- } else {
- bInArrayOrDict = FALSE;
- }
- m_bDictName = TRUE;
- }
- return bInArrayOrDict;
-}
-void CPDF_StreamContentParser::StartArray()
-{
- if (m_ObjectSize)
- if (m_pObjectStack[0]->GetType() != PDFOBJ_DICTIONARY && m_pObjectStack[m_ObjectSize - 1]->GetType() == PDFOBJ_ARRAY) {
- return;
- }
- CPDF_Array* pArray = FX_NEW CPDF_Array;
- AddContainer(pArray);
-}
-void CPDF_StreamContentParser::EndArray()
-{
- if (m_ObjectSize == 0) {
- return;
- }
- CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
- if (pCurObj->GetType() != PDFOBJ_ARRAY) {
- return;
- }
- m_ObjectSize --;
- if (m_ObjectSize == 0) {
- AddObjectParam(pCurObj);
- } else {
- if (!m_pObjectState[m_ObjectSize]) {
- pCurObj->Release();
- }
- }
- m_pObjectState[m_ObjectSize] = FALSE;
-}
-void CPDF_StreamContentParser::StartDict()
-{
- CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
- AddContainer(pDict);
- m_bDictName = TRUE;
-}
-void CPDF_StreamContentParser::EndDict()
-{
- if (m_ObjectSize == 0) {
- return;
- }
- CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
- if (pCurObj->GetType() != PDFOBJ_DICTIONARY) {
- return;
- }
- m_ObjectSize --;
- if (m_ObjectSize == 0) {
- AddObjectParam(pCurObj);
- } else {
- if (!m_pObjectState[m_ObjectSize]) {
- pCurObj->Release();
- }
- }
- m_pObjectState[m_ObjectSize] = FALSE;
-}
-void CPDF_StreamContentParser::EndName()
-{
- if (m_ObjectSize == 0) {
- AddNameParam((FX_LPCSTR)m_pWordBuf, m_WordSize);
- return;
- }
- CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1];
- if (pCurObj->GetType() == PDFOBJ_ARRAY) {
- ((CPDF_Array*)pCurObj)->AddName(CFX_ByteString(m_pWordBuf, m_WordSize));
- } else {
- if (m_bDictName) {
- FXSYS_memcpy32(m_pDictName, m_pWordBuf, m_WordSize);
- m_pDictName[m_WordSize] = 0;
- } else {
- if (m_pDictName[0] != 0) {
- ((CPDF_Dictionary*)pCurObj)->SetAtName((FX_LPCSTR)m_pDictName, CFX_ByteString(m_pWordBuf, m_WordSize));
- }
- }
- m_bDictName = !m_bDictName;
- }
-}
-void CPDF_StreamContentParser::EndNumber()
-{
- if (m_ObjectSize == 0) {
- AddNumberParam((FX_LPCSTR)m_pWordBuf, m_WordSize);
- return;
- }
- CPDF_Number *pObj = FX_NEW CPDF_Number(CFX_ByteStringC(m_pWordBuf, m_WordSize));
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
-}
-extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf);
-void CPDF_StreamContentParser::EndHexString()
-{
- CPDF_String *pObj = FX_NEW CPDF_String(_FPDF_ByteStringFromHex(m_StringBuf), TRUE);
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
-}
-void CPDF_StreamContentParser::EndString()
-{
- CPDF_String *pObj = FX_NEW CPDF_String(m_StringBuf.GetByteString());
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
-}
-void CPDF_StreamContentParser::Handle_BeginImage(void)
-{
- m_WordState = 9;
- m_InlineImageState = 0;
- m_StringBuf.Clear();
-}
-void _PDF_ReplaceAbbr(CPDF_Object* pObj);
-void CPDF_StreamContentParser::EndImageDict()
-{
- if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() ||
- FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(), m_StringBuf.GetSize())) {
- m_WordState = 0;
- StartDict();
- InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize());
- Finish();
- m_bSameLastDict = FALSE;
- if (m_pLastImageDict && m_bReleaseLastDict) {
- m_pLastImageDict->Release();
- m_pLastImageDict = NULL;
- }
- if (!m_ObjectSize) {
- m_InlineImageState = 0;
- return;
- }
- m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize];
- m_bReleaseLastDict = !m_pObjectState[m_ObjectSize];
- m_pObjectState[m_ObjectSize] = FALSE;
- _PDF_ReplaceAbbr(m_pLastImageDict);
- m_LastImageDict.TakeOver(m_StringBuf);
- if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) {
- CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
- if (pCSObj->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = pCSObj->GetString();
- if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) {
- pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
- if (pCSObj) {
- if (!pCSObj->GetObjNum()) {
- pCSObj = pCSObj->Clone();
- }
- m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument);
- }
- }
- }
- }
- } else {
- m_bSameLastDict = TRUE;
- }
- m_ImageSrcBuf.Clear();
- if (m_pLastCloneImageDict) {
- m_pLastCloneImageDict->Release();
- }
- m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone();
- if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) {
- m_WordState = 10;
- m_InlineImageState = 0;
- } else {
- int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width"));
- int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height"));
- int OrigSize = 0;
- CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
- if (pCSObj != NULL) {
- int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent"));
- int nComponents = 1;
- CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj);
- if (pCS == NULL) {
- nComponents = 3;
- } else {
- nComponents = pCS->CountComponents();
- m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
- }
- int pitch = (width * bpc * nComponents + 7) / 8;
- OrigSize = pitch * height;
- } else {
- OrigSize = ((width + 7) / 8) * height;
- }
- m_ImageSrcBuf.AppendBlock(NULL, OrigSize);
- m_WordState = 11;
- m_InlineImageState = 0;
- }
-}
-void CPDF_StreamContentParser::EndInlineImage()
-{
- CFX_AffineMatrix ImageMatrix;
- ImageMatrix.Copy(m_pCurStates->m_CTM);
- ImageMatrix.Concat(m_mtContentToUser);
- m_LastImageData.CopyData(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize());
- CPDF_Stream* pStream = CPDF_Stream::Create(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize(),
- m_pLastCloneImageDict);
- m_ImageSrcBuf.DetachBuffer();
- m_pLastCloneImageDict = NULL;
- CPDF_InlineImages* pImages = FX_NEW CPDF_InlineImages;
- pImages->m_pStream = pStream;
- SetGraphicStates(pImages, !m_pLastCloneImageDict->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE);
- pImages->AddMatrix(ImageMatrix);
- m_pObjectList->m_ObjectList.AddTail(pImages);
- m_WordState = 0;
-}
-#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274)
-#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e)
-#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166)
-void CPDF_StreamContentParser::EndKeyword()
-{
- CPDF_Object *pObj = NULL;
- if (m_WordSize == 4) {
- if (*(FX_DWORD*)m_pWordBuf == FXDWORD_TRUE) {
- pObj = CPDF_Boolean::Create(TRUE);
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
- return;
- } else if (*(FX_DWORD*)m_pWordBuf == FXDWORD_NULL) {
- pObj = CPDF_Null::Create();
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
- return;
- }
- } else if (m_WordSize == 5) {
- if (*(FX_DWORD*)m_pWordBuf == FXDWORD_FALS && m_pWordBuf[4] == 'e') {
- pObj = CPDF_Boolean::Create(FALSE);
- if (!SetToCurObj(pObj)) {
- pObj->Release();
- }
- return;
- }
- }
- m_pWordBuf[m_WordSize] = 0;
- OnOperator((char*)m_pWordBuf);
- ClearAllParams();
-}
-#define PAGEPARSE_STAGE_PARSE 2
-#define PAGEPARSE_STAGE_CHECKCLIP 3
-CPDF_ContentParser::CPDF_ContentParser()
-{
- m_pParser = NULL;
- m_Status = Ready;
- m_pStreamFilter = NULL;
- m_pType3Char = NULL;
-}
-CPDF_ContentParser::~CPDF_ContentParser()
-{
- Clear();
-}
-void CPDF_ContentParser::Clear()
-{
- if (m_pParser) {
- delete m_pParser;
- }
- if (m_pStreamFilter) {
- delete m_pStreamFilter;
- }
- m_pParser = NULL;
- m_Status = Ready;
-}
-void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions)
-{
- if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) {
- m_Status = Done;
- return;
- }
- m_pObjects = pPage;
- m_bForm = FALSE;
- if (pOptions) {
- m_Options = *pOptions;
- }
- CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
- if (pContent == NULL) {
- m_Status = Done;
- return;
- }
- if (pContent->GetType() == PDFOBJ_STREAM) {
- m_nStreams = 1;
- } else if (pContent->GetType() == PDFOBJ_ARRAY) {
- m_nStreams = ((CPDF_Array*)pContent)->GetCount();
- } else {
- m_Status = Done;
- return;
- }
- m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
- m_CurrentOffset = 0;
- m_pParser = FX_NEW CPDF_StreamContentParser;
- m_pParser->Initialize();
- m_pParser->PrepareParse(pPage->m_pDocument, pPage->m_pResources, NULL, NULL, pPage,
- pPage->m_pResources, &pPage->m_BBox, &m_Options, NULL, 0);
- m_pParser->m_pCurStates->m_ColorState.GetModify()->Default();
-}
-void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
- CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
-{
- m_pType3Char = pType3Char;
- m_pObjects = pForm;
- m_bForm = TRUE;
- CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix"));
- if (pGraphicStates) {
- form_matrix.Concat(pGraphicStates->m_CTM);
- }
- CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox"));
- CFX_FloatRect form_bbox;
- CPDF_Path ClipPath;
- if (pBBox) {
- form_bbox = pBBox->GetRect();
- ClipPath.New();
- ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top);
- ClipPath.Transform(&form_matrix);
- if (pParentMatrix) {
- ClipPath.Transform(pParentMatrix);
- }
- form_bbox.Transform(&form_matrix);
- }
- CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
- m_pParser = FX_NEW CPDF_StreamContentParser;
- m_pParser->Initialize();
- m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm,
- pResources, &form_bbox, pOptions, pGraphicStates, level);
- m_pParser->m_pCurStates->m_CTM = form_matrix;
- if (ClipPath.NotNull()) {
- m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE);
- }
- if (pForm->m_Transparency & PDFTRANS_GROUP) {
- CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify();
- pData->m_BlendType = FXDIB_BLEND_NORMAL;
- pData->m_StrokeAlpha = 1.0f;
- pData->m_FillAlpha = 1.0f;
- pData->m_pSoftMask = NULL;
- }
- m_pStreamFilter = pForm->m_pFormStream->GetStreamFilter();
- m_nStreams = 1;
- m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
- m_CurrentOffset = 0;
-}
-void CPDF_ContentParser::Continue(IFX_Pause* pPause)
-{
- while (m_Status == ToBeContinued) {
- if (m_InternalStage == PAGEPARSE_STAGE_PARSE) {
- if (m_pStreamFilter == NULL) {
- if (m_CurrentOffset == m_nStreams) {
- m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
- if (m_pType3Char) {
- m_pType3Char->m_bColored = m_pParser->m_bColored;
- m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000);
- m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000);
- m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000);
- m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000);
- m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000);
- m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing;
- }
- delete m_pParser;
- m_pParser = NULL;
- continue;
- }
- CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
- if (pContent->GetType() == PDFOBJ_STREAM) {
- m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter();
- } else {
- CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_CurrentOffset);
- if (pStream == NULL) {
- m_CurrentOffset ++;
- continue;
- }
- m_pStreamFilter = pStream->GetStreamFilter();
- }
- }
- FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, STREAM_PARSE_BUFSIZE);
- m_pParser->InputData(m_pParser->m_pStreamBuf, len);
- if (m_pParser->m_bAbort) {
- delete m_pStreamFilter;
- m_pStreamFilter = NULL;
- m_Status = Done;
- delete m_pParser;
- m_pParser = NULL;
- return;
- }
- if (len < STREAM_PARSE_BUFSIZE) {
- m_pParser->Finish();
- m_CurrentOffset ++;
- delete m_pStreamFilter;
- m_pStreamFilter = NULL;
- }
- if (pPause && pPause->NeedToPauseNow()) {
- return;
- }
- }
- if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
- FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos);
- if (pObj == NULL) {
- continue;
- }
- if (pObj->m_ClipPath.IsNull()) {
- continue;
- }
- if (pObj->m_ClipPath.GetPathCount() != 1) {
- continue;
- }
- if (pObj->m_ClipPath.GetTextCount()) {
- continue;
- }
- CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
- if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) {
- continue;
- }
- CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
- ClipPath.GetPointX(2), ClipPath.GetPointY(2));
- CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
- if (old_rect.Contains(obj_rect)) {
- pObj->m_ClipPath.SetNull();
- }
- }
- if (m_pObjects->m_ObjectList.GetCount() == 1) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetAt(m_pObjects->m_ObjectList.GetHeadPosition());
- if (pObj && pObj->m_Type == PDFPAGE_TEXT) {
- CPDF_TextObject* pText = (CPDF_TextObject*)pObj;
- }
- }
- m_Status = Done;
- return;
- }
- }
-}
-int CPDF_ContentParser::EstimateProgress()
-{
- if (m_Status == Ready) {
- return 0;
- }
- if (m_Status == Done) {
- return 100;
- }
- if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
- return 90;
- }
- if (m_pStreamFilter == NULL) {
- return 90 * m_CurrentOffset / m_nStreams;
- }
- int total_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_nStreams;
- int parsed_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_CurrentOffset +
- m_pStreamFilter->GetSrcPos();
- return 90 * parsed_raw_size / total_raw_size;
-}
-CPDF_InlineImages::CPDF_InlineImages()
-{
- m_Type = PDFPAGE_INLINES;
- m_pStream = NULL;
- m_pBitmap = NULL;
-}
-CPDF_InlineImages::~CPDF_InlineImages()
-{
- if (m_pStream) {
- m_pStream->Release();
- }
- if (m_pBitmap) {
- delete m_pBitmap;
- }
-}
-void CPDF_InlineImages::AddMatrix(CFX_AffineMatrix& matrix)
-{
- m_Matrices.Add(matrix);
- CFX_FloatRect rect = matrix.GetUnitRect();
- if (m_Matrices.GetSize() > 1) {
- CFX_FloatRect rect1(m_Left, m_Bottom, m_Right, m_Top);
- rect.Union(rect1);
- }
- m_Left = rect.left;
- m_Right = rect.right;
- m_Top = rect.top;
- m_Bottom = rect.bottom;
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "pageint.h" +#if defined(_FPDFAPI_MINI_) +extern const FX_LPCSTR _PDF_CharType; +void CPDF_StreamContentParser::InputData(FX_LPCBYTE src_buf, FX_DWORD src_size) +{ + if (m_Level > _FPDF_MAX_FORM_LEVEL_) { + return; + } + for (FX_DWORD i = 0; i < src_size; i ++) { + int ch = src_buf[i]; + int type = _PDF_CharType[ch]; +start: + switch (m_WordState) { + case 0: + if (type == 'W') { + } else if (type == 'N') { + m_WordState = 5; + m_pWordBuf[0] = ch; + m_WordSize = 1; + } else if (type == 'R') { + m_WordState = 4; + m_pWordBuf[0] = ch; + m_WordSize = 1; + } else switch (ch) { + case '/': + m_WordState = 2; + m_WordSize = 0; + break; + case '[': + StartArray(); + break; + case ']': + EndArray(); + break; + case '(': + m_WordState = 7; + m_StringLevel = 1; + m_StringState = 0; + m_StringBuf.Clear(); + break; + case '<': + m_WordState = 3; + break; + case '>': + m_WordState = 8; + break; + case '%': + m_WordState = 1; + break; + } + break; + case 1: + if (ch == '\n' || ch == '\r') { + m_WordState = 0; + } + break; + case 2: + if (type != 'R' && type != 'N') { + EndName(); + m_WordState = 0; + goto start; + } + if (m_WordSize < 256) { + m_pWordBuf[m_WordSize++] = ch; + } + break; + case 3: + if (ch == '<') { + StartDict(); + m_WordState = 0; + } else { + m_StringBuf.Clear(); + m_WordState = 6; + goto start; + } + break; + case 4: + if (type != 'R' && type != 'N') { + m_WordState = 0; + EndKeyword(); + if (m_bAbort) { + return; + } + goto start; + } + if (m_WordSize < 256) { + m_pWordBuf[m_WordSize++] = ch; + } + break; + case 5: + if (type != 'N') { + EndNumber(); + m_WordState = 0; + goto start; + } + if (m_WordSize < 256) { + m_pWordBuf[m_WordSize++] = ch; + } + break; + case 6: + if (ch == '>') { + EndHexString(); + m_WordState = 0; + } else { + m_StringBuf.AppendByte(ch); + } + break; + case 7: + switch (m_StringState) { + case 0: + if (ch == ')') { + m_StringLevel --; + if (m_StringLevel == 0) { + EndString(); + m_WordState = 0; + break; + } + m_StringBuf.AppendByte(')'); + } else if (ch == '(') { + m_StringLevel ++; + m_StringBuf.AppendByte('('); + } else if (ch == '\\') { + m_StringState = 1; + } else { + m_StringBuf.AppendByte((char)ch); + } + break; + case 1: + if (ch >= '0' && ch <= '7') { + m_EscCode = ch - '0'; + m_StringState = 2; + break; + } + if (ch == 'n') { + m_StringBuf.AppendByte('\n'); + } else if (ch == 'r') { + m_StringBuf.AppendByte('\r'); + } else if (ch == 't') { + m_StringBuf.AppendByte('\t'); + } else if (ch == 'b') { + m_StringBuf.AppendByte('\b'); + } else if (ch == 'f') { + m_StringBuf.AppendByte('\f'); + } else if (ch == '\\') { + m_StringBuf.AppendByte('\\'); + } else if (ch == '(') { + m_StringBuf.AppendByte('('); + } else if (ch == ')') { + m_StringBuf.AppendByte(')'); + } else if (ch == '\r') { + m_StringState = 4; + break; + } else if (ch == '\n') { + } else { + m_StringBuf.AppendByte(ch); + } + m_StringState = 0; + break; + case 2: + if (ch >= '0' && ch <= '7') { + m_EscCode = m_EscCode * 8 + ch - '0'; + m_StringState = 3; + } else { + m_StringBuf.AppendByte(m_EscCode); + m_StringState = 0; + goto start; + } + break; + case 3: + if (ch >= '0' && ch <= '7') { + m_EscCode = m_EscCode * 8 + ch - '0'; + m_StringBuf.AppendByte(m_EscCode); + m_StringState = 0; + } else { + m_StringBuf.AppendByte(m_EscCode); + m_StringState = 0; + goto start; + } + break; + case 4: + m_StringState = 0; + if (ch != '\n') { + goto start; + } + break; + } + break; + case 8: + m_WordState = 0; + if (ch == '>') { + EndDict(); + } else { + goto start; + } + break; + case 9: + switch (m_InlineImageState) { + case 0: + if (type == 'W' || type == 'D') { + m_InlineImageState = 1; + m_InlineWhiteChar = ch; + } else { + m_StringBuf.AppendByte(ch); + } + break; + case 1: + m_StringBuf.AppendByte(m_InlineWhiteChar); + if (ch == 'I') { + m_InlineImageState = 2; + } else { + m_InlineImageState = 0; + goto start; + } + break; + case 2: + if (ch == 'D') { + m_InlineImageState = 3; + } else { + m_StringBuf.AppendByte('I'); + m_InlineImageState = 0; + goto start; + } + break; + case 3: + EndImageDict(); + break; + } + break; + case 10: + switch (m_InlineImageState) { + case 0: + if (type == 'W') { + m_InlineImageState = 1; + m_InlineWhiteChar = ch; + } else { + m_ImageSrcBuf.AppendByte(ch); + } + break; + case 1: + if (ch == 'E') { + m_InlineImageState = 2; + } else { + m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); + m_InlineImageState = 0; + goto start; + } + break; + case 2: + if (ch == 'I') { + m_InlineImageState = 3; + } else { + m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); + m_ImageSrcBuf.AppendByte('E'); + m_InlineImageState = 0; + goto start; + } + break; + case 3: + if (type == 'W') { + EndInlineImage(); + } else { + m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); + m_ImageSrcBuf.AppendByte('E'); + m_ImageSrcBuf.AppendByte('I'); + m_InlineImageState = 0; + goto start; + } + break; + } + break; + case 11: + if (m_InlineImageState < m_ImageSrcBuf.GetSize()) { + m_ImageSrcBuf.GetBuffer()[m_InlineImageState ++] = ch; + } else { + if (ch == 'I') { + EndInlineImage(); + } + } + break; + } + } +} +void CPDF_StreamContentParser::Finish() +{ + switch (m_WordState) { + case 0: + break; + case 1: + break; + case 2: + EndName(); + break; + case 3: + break; + case 4: + EndKeyword(); + break; + case 5: + EndNumber(); + break; + case 6: + EndHexString(); + break; + case 7: + EndString(); + break; + case 8: + break; + case 9: + break; + case 10: + EndInlineImage(); + break; + } + m_WordState = 0; +} +void CPDF_StreamContentParser::AddContainer(CPDF_Object* pObject) +{ + if (m_ObjectSize) { + m_pObjectState[m_ObjectSize] = SetToCurObj(pObject); + } + FXSYS_assert(m_ObjectSize < _FPDF_MAX_OBJECT_STACK_SIZE_); + m_pObjectStack[m_ObjectSize++] = pObject; +} +FX_BOOL CPDF_StreamContentParser::SetToCurObj(CPDF_Object* pObject) +{ + if (m_ObjectSize == 0) { + AddObjectParam(pObject); + return TRUE; + } + FX_BOOL bInArrayOrDict = TRUE; + CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; + if (pCurObj->GetType() == PDFOBJ_ARRAY) { + ((CPDF_Array*)pCurObj)->Add(pObject, m_pDocument); + } else { + if (!m_bDictName && m_pDictName[0]) { + ((CPDF_Dictionary*)pCurObj)->SetAt((FX_LPCSTR)m_pDictName, pObject, m_pDocument); + } else { + bInArrayOrDict = FALSE; + } + m_bDictName = TRUE; + } + return bInArrayOrDict; +} +void CPDF_StreamContentParser::StartArray() +{ + if (m_ObjectSize) + if (m_pObjectStack[0]->GetType() != PDFOBJ_DICTIONARY && m_pObjectStack[m_ObjectSize - 1]->GetType() == PDFOBJ_ARRAY) { + return; + } + CPDF_Array* pArray = FX_NEW CPDF_Array; + AddContainer(pArray); +} +void CPDF_StreamContentParser::EndArray() +{ + if (m_ObjectSize == 0) { + return; + } + CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; + if (pCurObj->GetType() != PDFOBJ_ARRAY) { + return; + } + m_ObjectSize --; + if (m_ObjectSize == 0) { + AddObjectParam(pCurObj); + } else { + if (!m_pObjectState[m_ObjectSize]) { + pCurObj->Release(); + } + } + m_pObjectState[m_ObjectSize] = FALSE; +} +void CPDF_StreamContentParser::StartDict() +{ + CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; + AddContainer(pDict); + m_bDictName = TRUE; +} +void CPDF_StreamContentParser::EndDict() +{ + if (m_ObjectSize == 0) { + return; + } + CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; + if (pCurObj->GetType() != PDFOBJ_DICTIONARY) { + return; + } + m_ObjectSize --; + if (m_ObjectSize == 0) { + AddObjectParam(pCurObj); + } else { + if (!m_pObjectState[m_ObjectSize]) { + pCurObj->Release(); + } + } + m_pObjectState[m_ObjectSize] = FALSE; +} +void CPDF_StreamContentParser::EndName() +{ + if (m_ObjectSize == 0) { + AddNameParam((FX_LPCSTR)m_pWordBuf, m_WordSize); + return; + } + CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; + if (pCurObj->GetType() == PDFOBJ_ARRAY) { + ((CPDF_Array*)pCurObj)->AddName(CFX_ByteString(m_pWordBuf, m_WordSize)); + } else { + if (m_bDictName) { + FXSYS_memcpy32(m_pDictName, m_pWordBuf, m_WordSize); + m_pDictName[m_WordSize] = 0; + } else { + if (m_pDictName[0] != 0) { + ((CPDF_Dictionary*)pCurObj)->SetAtName((FX_LPCSTR)m_pDictName, CFX_ByteString(m_pWordBuf, m_WordSize)); + } + } + m_bDictName = !m_bDictName; + } +} +void CPDF_StreamContentParser::EndNumber() +{ + if (m_ObjectSize == 0) { + AddNumberParam((FX_LPCSTR)m_pWordBuf, m_WordSize); + return; + } + CPDF_Number *pObj = FX_NEW CPDF_Number(CFX_ByteStringC(m_pWordBuf, m_WordSize)); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } +} +extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf); +void CPDF_StreamContentParser::EndHexString() +{ + CPDF_String *pObj = FX_NEW CPDF_String(_FPDF_ByteStringFromHex(m_StringBuf), TRUE); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } +} +void CPDF_StreamContentParser::EndString() +{ + CPDF_String *pObj = FX_NEW CPDF_String(m_StringBuf.GetByteString()); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } +} +void CPDF_StreamContentParser::Handle_BeginImage(void) +{ + m_WordState = 9; + m_InlineImageState = 0; + m_StringBuf.Clear(); +} +void _PDF_ReplaceAbbr(CPDF_Object* pObj); +void CPDF_StreamContentParser::EndImageDict() +{ + if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() || + FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(), m_StringBuf.GetSize())) { + m_WordState = 0; + StartDict(); + InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize()); + Finish(); + m_bSameLastDict = FALSE; + if (m_pLastImageDict && m_bReleaseLastDict) { + m_pLastImageDict->Release(); + m_pLastImageDict = NULL; + } + if (!m_ObjectSize) { + m_InlineImageState = 0; + return; + } + m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize]; + m_bReleaseLastDict = !m_pObjectState[m_ObjectSize]; + m_pObjectState[m_ObjectSize] = FALSE; + _PDF_ReplaceAbbr(m_pLastImageDict); + m_LastImageDict.TakeOver(m_StringBuf); + if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) { + CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = pCSObj->GetString(); + if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) { + pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); + if (pCSObj) { + if (!pCSObj->GetObjNum()) { + pCSObj = pCSObj->Clone(); + } + m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); + } + } + } + } + } else { + m_bSameLastDict = TRUE; + } + m_ImageSrcBuf.Clear(); + if (m_pLastCloneImageDict) { + m_pLastCloneImageDict->Release(); + } + m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone(); + if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) { + m_WordState = 10; + m_InlineImageState = 0; + } else { + int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width")); + int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height")); + int OrigSize = 0; + CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj != NULL) { + int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent")); + int nComponents = 1; + CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj); + if (pCS == NULL) { + nComponents = 3; + } else { + nComponents = pCS->CountComponents(); + m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); + } + int pitch = (width * bpc * nComponents + 7) / 8; + OrigSize = pitch * height; + } else { + OrigSize = ((width + 7) / 8) * height; + } + m_ImageSrcBuf.AppendBlock(NULL, OrigSize); + m_WordState = 11; + m_InlineImageState = 0; + } +} +void CPDF_StreamContentParser::EndInlineImage() +{ + CFX_AffineMatrix ImageMatrix; + ImageMatrix.Copy(m_pCurStates->m_CTM); + ImageMatrix.Concat(m_mtContentToUser); + m_LastImageData.CopyData(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize()); + CPDF_Stream* pStream = CPDF_Stream::Create(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize(), + m_pLastCloneImageDict); + m_ImageSrcBuf.DetachBuffer(); + m_pLastCloneImageDict = NULL; + CPDF_InlineImages* pImages = FX_NEW CPDF_InlineImages; + pImages->m_pStream = pStream; + SetGraphicStates(pImages, !m_pLastCloneImageDict->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE); + pImages->AddMatrix(ImageMatrix); + m_pObjectList->m_ObjectList.AddTail(pImages); + m_WordState = 0; +} +#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) +#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) +#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) +void CPDF_StreamContentParser::EndKeyword() +{ + CPDF_Object *pObj = NULL; + if (m_WordSize == 4) { + if (*(FX_DWORD*)m_pWordBuf == FXDWORD_TRUE) { + pObj = CPDF_Boolean::Create(TRUE); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } + return; + } else if (*(FX_DWORD*)m_pWordBuf == FXDWORD_NULL) { + pObj = CPDF_Null::Create(); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } + return; + } + } else if (m_WordSize == 5) { + if (*(FX_DWORD*)m_pWordBuf == FXDWORD_FALS && m_pWordBuf[4] == 'e') { + pObj = CPDF_Boolean::Create(FALSE); + if (!SetToCurObj(pObj)) { + pObj->Release(); + } + return; + } + } + m_pWordBuf[m_WordSize] = 0; + OnOperator((char*)m_pWordBuf); + ClearAllParams(); +} +#define PAGEPARSE_STAGE_PARSE 2 +#define PAGEPARSE_STAGE_CHECKCLIP 3 +CPDF_ContentParser::CPDF_ContentParser() +{ + m_pParser = NULL; + m_Status = Ready; + m_pStreamFilter = NULL; + m_pType3Char = NULL; +} +CPDF_ContentParser::~CPDF_ContentParser() +{ + Clear(); +} +void CPDF_ContentParser::Clear() +{ + if (m_pParser) { + delete m_pParser; + } + if (m_pStreamFilter) { + delete m_pStreamFilter; + } + m_pParser = NULL; + m_Status = Ready; +} +void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) +{ + if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) { + m_Status = Done; + return; + } + m_pObjects = pPage; + m_bForm = FALSE; + if (pOptions) { + m_Options = *pOptions; + } + CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); + if (pContent == NULL) { + m_Status = Done; + return; + } + if (pContent->GetType() == PDFOBJ_STREAM) { + m_nStreams = 1; + } else if (pContent->GetType() == PDFOBJ_ARRAY) { + m_nStreams = ((CPDF_Array*)pContent)->GetCount(); + } else { + m_Status = Done; + return; + } + m_Status = ToBeContinued; + m_InternalStage = PAGEPARSE_STAGE_PARSE; + m_CurrentOffset = 0; + m_pParser = FX_NEW CPDF_StreamContentParser; + m_pParser->Initialize(); + m_pParser->PrepareParse(pPage->m_pDocument, pPage->m_pResources, NULL, NULL, pPage, + pPage->m_pResources, &pPage->m_BBox, &m_Options, NULL, 0); + m_pParser->m_pCurStates->m_ColorState.GetModify()->Default(); +} +void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix, + CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) +{ + m_pType3Char = pType3Char; + m_pObjects = pForm; + m_bForm = TRUE; + CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix")); + if (pGraphicStates) { + form_matrix.Concat(pGraphicStates->m_CTM); + } + CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); + CFX_FloatRect form_bbox; + CPDF_Path ClipPath; + if (pBBox) { + form_bbox = pBBox->GetRect(); + ClipPath.New(); + ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top); + ClipPath.Transform(&form_matrix); + if (pParentMatrix) { + ClipPath.Transform(pParentMatrix); + } + form_bbox.Transform(&form_matrix); + } + CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + m_pParser = FX_NEW CPDF_StreamContentParser; + m_pParser->Initialize(); + m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm, + pResources, &form_bbox, pOptions, pGraphicStates, level); + m_pParser->m_pCurStates->m_CTM = form_matrix; + if (ClipPath.NotNull()) { + m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE); + } + if (pForm->m_Transparency & PDFTRANS_GROUP) { + CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify(); + pData->m_BlendType = FXDIB_BLEND_NORMAL; + pData->m_StrokeAlpha = 1.0f; + pData->m_FillAlpha = 1.0f; + pData->m_pSoftMask = NULL; + } + m_pStreamFilter = pForm->m_pFormStream->GetStreamFilter(); + m_nStreams = 1; + m_Status = ToBeContinued; + m_InternalStage = PAGEPARSE_STAGE_PARSE; + m_CurrentOffset = 0; +} +void CPDF_ContentParser::Continue(IFX_Pause* pPause) +{ + while (m_Status == ToBeContinued) { + if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { + if (m_pStreamFilter == NULL) { + if (m_CurrentOffset == m_nStreams) { + m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; + if (m_pType3Char) { + m_pType3Char->m_bColored = m_pParser->m_bColored; + m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000); + m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000); + m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000); + m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000); + m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000); + m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing; + } + delete m_pParser; + m_pParser = NULL; + continue; + } + CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); + if (pContent->GetType() == PDFOBJ_STREAM) { + m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter(); + } else { + CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_CurrentOffset); + if (pStream == NULL) { + m_CurrentOffset ++; + continue; + } + m_pStreamFilter = pStream->GetStreamFilter(); + } + } + FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, STREAM_PARSE_BUFSIZE); + m_pParser->InputData(m_pParser->m_pStreamBuf, len); + if (m_pParser->m_bAbort) { + delete m_pStreamFilter; + m_pStreamFilter = NULL; + m_Status = Done; + delete m_pParser; + m_pParser = NULL; + return; + } + if (len < STREAM_PARSE_BUFSIZE) { + m_pParser->Finish(); + m_CurrentOffset ++; + delete m_pStreamFilter; + m_pStreamFilter = NULL; + } + if (pPause && pPause->NeedToPauseNow()) { + return; + } + } + if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { + FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); + if (pObj == NULL) { + continue; + } + if (pObj->m_ClipPath.IsNull()) { + continue; + } + if (pObj->m_ClipPath.GetPathCount() != 1) { + continue; + } + if (pObj->m_ClipPath.GetTextCount()) { + continue; + } + CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); + if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { + continue; + } + CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), + ClipPath.GetPointX(2), ClipPath.GetPointY(2)); + CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); + if (old_rect.Contains(obj_rect)) { + pObj->m_ClipPath.SetNull(); + } + } + if (m_pObjects->m_ObjectList.GetCount() == 1) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetAt(m_pObjects->m_ObjectList.GetHeadPosition()); + if (pObj && pObj->m_Type == PDFPAGE_TEXT) { + CPDF_TextObject* pText = (CPDF_TextObject*)pObj; + } + } + m_Status = Done; + return; + } + } +} +int CPDF_ContentParser::EstimateProgress() +{ + if (m_Status == Ready) { + return 0; + } + if (m_Status == Done) { + return 100; + } + if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { + return 90; + } + if (m_pStreamFilter == NULL) { + return 90 * m_CurrentOffset / m_nStreams; + } + int total_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_nStreams; + int parsed_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_CurrentOffset + + m_pStreamFilter->GetSrcPos(); + return 90 * parsed_raw_size / total_raw_size; +} +CPDF_InlineImages::CPDF_InlineImages() +{ + m_Type = PDFPAGE_INLINES; + m_pStream = NULL; + m_pBitmap = NULL; +} +CPDF_InlineImages::~CPDF_InlineImages() +{ + if (m_pStream) { + m_pStream->Release(); + } + if (m_pBitmap) { + delete m_pBitmap; + } +} +void CPDF_InlineImages::AddMatrix(CFX_AffineMatrix& matrix) +{ + m_Matrices.Add(matrix); + CFX_FloatRect rect = matrix.GetUnitRect(); + if (m_Matrices.GetSize() > 1) { + CFX_FloatRect rect1(m_Left, m_Bottom, m_Right, m_Top); + rect.Union(rect1); + } + m_Left = rect.left; + m_Right = rect.right; + m_Top = rect.top; + m_Bottom = rect.bottom; +} +#endif diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp index 2f0a18d62e..cafca2623c 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp @@ -1,1146 +1,1146 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "pageint.h"
-#include <limits.h>
-extern const FX_LPCSTR _PDF_OpCharType =
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"
- "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII"
- "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII"
- "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII"
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
-FX_BOOL _PDF_HasInvalidOpChar(FX_LPCSTR op)
-{
- if(!op) {
- return FALSE;
- }
- FX_BYTE ch;
- while((ch = *op++)) {
- if(_PDF_OpCharType[ch] == 'I') {
- return TRUE;
- }
- }
- return FALSE;
-}
-FX_DWORD CPDF_StreamContentParser::Parse(FX_LPCBYTE pData, FX_DWORD dwSize, FX_DWORD max_cost)
-{
- if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
- return dwSize;
- }
- FX_DWORD InitObjCount = m_pObjectList->CountObjects();
- CPDF_StreamParser syntax(pData, dwSize);
- m_pSyntax = &syntax;
- m_CompatCount = 0;
- while (1) {
- FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount;
- if (max_cost && cost >= max_cost) {
- break;
- }
- switch (syntax.ParseNextElement()) {
- case CPDF_StreamParser::EndOfData:
- return m_pSyntax->GetPos();
- case CPDF_StreamParser::Keyword:
- if(!OnOperator((char*)syntax.GetWordBuf()) && _PDF_HasInvalidOpChar((char*)syntax.GetWordBuf())) {
- m_bAbort = TRUE;
- }
- if (m_bAbort) {
- return m_pSyntax->GetPos();
- }
- ClearAllParams();
- break;
- case CPDF_StreamParser::Number:
- AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize());
- break;
- case CPDF_StreamParser::Name:
- AddNameParam((FX_LPCSTR)syntax.GetWordBuf() + 1, syntax.GetWordSize() - 1);
- break;
- default:
- AddObjectParam(syntax.GetObject());
- }
- }
- return m_pSyntax->GetPos();
-}
-void _PDF_ReplaceAbbr(CPDF_Object* pObj);
-void CPDF_StreamContentParser::Handle_BeginImage()
-{
- FX_FILESIZE savePos = m_pSyntax->GetPos();
- CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- if (type == CPDF_StreamParser::Keyword) {
- CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize());
- if (bsKeyword != FX_BSTRC("ID")) {
- m_pSyntax->SetPos(savePos);
- pDict->Release();
- return;
- }
- }
- if (type != CPDF_StreamParser::Name) {
- break;
- }
- CFX_ByteString key((FX_LPCSTR)m_pSyntax->GetWordBuf() + 1, m_pSyntax->GetWordSize() - 1);
- CPDF_Object* pObj = m_pSyntax->ReadNextObject();
- if (!key.IsEmpty()) {
- pDict->SetAt(key, pObj, m_pDocument);
- } else {
- pObj->Release();
- }
- }
- _PDF_ReplaceAbbr(pDict);
- CPDF_Object* pCSObj = NULL;
- if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) {
- pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
- if (pCSObj->GetType() == PDFOBJ_NAME) {
- CFX_ByteString name = pCSObj->GetString();
- if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) {
- pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
- if (pCSObj && !pCSObj->GetObjNum()) {
- pCSObj = pCSObj->Clone();
- pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument);
- }
- }
- }
- }
- CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage);
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- if (type == CPDF_StreamParser::EndOfData) {
- break;
- }
- if (type != CPDF_StreamParser::Keyword) {
- continue;
- }
- if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &&
- m_pSyntax->GetWordBuf()[1] == 'I') {
- break;
- }
- }
- if (m_Options.m_bTextOnly) {
- if (pStream) {
- pStream->Release();
- } else {
- pDict->Release();
- }
- return;
- }
- pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image"));
- CPDF_ImageObject *pImgObj = AddImage(pStream, NULL, TRUE);
- if (!pImgObj) {
- if (pStream) {
- pStream->Release();
- } else {
- pDict->Release();
- }
- }
-}
-void CPDF_StreamContentParser::ParsePathObject()
-{
- FX_FLOAT params[6] = {0};
- int nParams = 0;
- int last_pos = m_pSyntax->GetPos();
- while (1) {
- CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
- FX_BOOL bProcessed = TRUE;
- switch (type) {
- case CPDF_StreamParser::EndOfData:
- return;
- case CPDF_StreamParser::Keyword: {
- int len = m_pSyntax->GetWordSize();
- if (len == 1) {
- switch (m_pSyntax->GetWordBuf()[0]) {
- case 'm':
- AddPathPoint(params[0], params[1], FXPT_MOVETO);
- nParams = 0;
- break;
- case 'l':
- AddPathPoint(params[0], params[1], FXPT_LINETO);
- nParams = 0;
- break;
- case 'c':
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- AddPathPoint(params[4], params[5], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case 'v':
- AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case 'y':
- AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
- nParams = 0;
- break;
- case 'h':
- Handle_ClosePath();
- nParams = 0;
- break;
- default:
- bProcessed = FALSE;
- break;
- }
- } else if (len == 2) {
- if (m_pSyntax->GetWordBuf()[0] == 'r' && m_pSyntax->GetWordBuf()[1] == 'e') {
- AddPathRect(params[0], params[1], params[2], params[3]);
- nParams = 0;
- } else {
- bProcessed = FALSE;
- }
- } else {
- bProcessed = FALSE;
- }
- if (bProcessed) {
- last_pos = m_pSyntax->GetPos();
- }
- break;
- }
- case CPDF_StreamParser::Number: {
- if (nParams == 6) {
- break;
- }
- FX_BOOL bInteger;
- int value;
- FX_atonum(CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), bInteger, &value);
- params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value;
- break;
- }
- default:
- bProcessed = FALSE;
- }
- if (!bProcessed) {
- m_pSyntax->SetPos(last_pos);
- return;
- }
- }
-}
-CPDF_StreamParser::CPDF_StreamParser(const FX_BYTE* pData, FX_DWORD dwSize)
-{
- m_pBuf = pData;
- m_Size = dwSize;
- m_Pos = 0;
- m_pLastObj = NULL;
-}
-CPDF_StreamParser::~CPDF_StreamParser()
-{
- if (m_pLastObj) {
- m_pLastObj->Release();
- }
-}
-FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
-{
- if (pDecoder == NULL) {
- return (FX_DWORD) - 1;
- }
- int ncomps = pDecoder->CountComps();
- int bpc = pDecoder->GetBPC();
- int width = pDecoder->GetWidth();
- int height = pDecoder->GetHeight();
- int pitch = (width * ncomps * bpc + 7) / 8;
- if (height == 0 || pitch > (1 << 30) / height) {
- delete pDecoder;
- return -1;
- }
- dest_size = pitch * height;
- dest_buf = FX_Alloc( FX_BYTE, dest_size);
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE pLine = pDecoder->GetScanline(row);
- if (pLine == NULL) {
- break;
- }
- FXSYS_memcpy32(dest_buf + row * pitch, pLine, pitch);
- }
- FX_DWORD srcoff = pDecoder->GetSrcOffset();
- delete pDecoder;
- return srcoff;
-}
-ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
- const CPDF_Dictionary* pParams);
-FX_DWORD _A85Decode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
-FX_DWORD _HexDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
-FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams,
- FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size);
-FX_DWORD PDF_DecodeInlineStream(const FX_BYTE* src_buf, FX_DWORD limit,
- int width, int height, CFX_ByteString& decoder,
- CPDF_Dictionary* pParam, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
-{
- if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) {
- ICodec_ScanlineDecoder* pDecoder = FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam);
- return _DecodeAllScanlines(pDecoder, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) {
- return _A85Decode(src_buf, limit, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) {
- return _HexDecode(src_buf, limit, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) {
- return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
- return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) {
- ICodec_ScanlineDecoder* pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
- src_buf, limit, width, height, 0, pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1);
- return _DecodeAllScanlines(pDecoder, dest_buf, dest_size);
- } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) {
- return RunLengthDecode(src_buf, limit, dest_buf, dest_size);
- }
- dest_size = 0;
- dest_buf = 0;
- return (FX_DWORD) - 1;
-}
-extern const FX_LPCSTR _PDF_CharType;
-CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode)
-{
- if (m_Pos == m_Size) {
- return NULL;
- }
- if (_PDF_CharType[m_pBuf[m_Pos]] == 'W') {
- m_Pos ++;
- }
- CFX_ByteString Decoder;
- CPDF_Dictionary* pParam = NULL;
- CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter"));
- if (pFilter == NULL) {
- } else if (pFilter->GetType() == PDFOBJ_ARRAY) {
- Decoder = ((CPDF_Array*)pFilter)->GetString(0);
- CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
- if (pParams) {
- pParam = pParams->GetDict(0);
- }
- } else {
- Decoder = pFilter->GetString();
- pParam = pDict->GetDict(FX_BSTRC("DecodeParms"));
- }
- FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width"));
- FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height"));
- FX_DWORD OrigSize = 0;
- if (pCSObj != NULL) {
- FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent"));
- FX_DWORD nComponents = 1;
- CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj);
- if (pCS == NULL) {
- nComponents = 3;
- } else {
- nComponents = pCS->CountComponents();
- pDoc->GetPageData()->ReleaseColorSpace(pCSObj);
- }
- FX_DWORD pitch = width;
- if (bpc && pitch > INT_MAX / bpc) {
- return NULL;
- }
- pitch *= bpc;
- if (nComponents && pitch > INT_MAX / nComponents) {
- return NULL;
- }
- pitch *= nComponents;
- if (pitch > INT_MAX - 7) {
- return NULL;
- }
- pitch += 7;
- pitch /= 8;
- OrigSize = pitch;
- } else {
- if (width > INT_MAX - 7) {
- return NULL;
- }
- OrigSize = ((width + 7) / 8);
- }
- if (height && OrigSize > INT_MAX / height) {
- return NULL;
- }
- OrigSize *= height;
- FX_LPBYTE pData = NULL;
- FX_DWORD dwStreamSize;
- if (Decoder.IsEmpty()) {
- if (OrigSize > m_Size - m_Pos) {
- OrigSize = m_Size - m_Pos;
- }
- pData = FX_Alloc(FX_BYTE, OrigSize);
- FXSYS_memcpy32(pData, m_pBuf + m_Pos, OrigSize);
- dwStreamSize = OrigSize;
- m_Pos += OrigSize;
- } else {
- FX_DWORD dwDestSize = OrigSize;
- dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, Decoder, pParam,
- pData, dwDestSize);
- if ((int)dwStreamSize < 0) {
- return NULL;
- }
- if (bDecode) {
- m_Pos += dwStreamSize;
- dwStreamSize = dwDestSize;
- if (pFilter->GetType() == PDFOBJ_ARRAY) {
- ((CPDF_Array*)pFilter)->RemoveAt(0);
- CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
- if (pParams) {
- pParams->RemoveAt(0);
- }
- } else {
- pDict->RemoveAt(FX_BSTRC("Filter"));
- pDict->RemoveAt(FX_BSTRC("DecodeParms"));
- }
- } else {
- if (pData) {
- FX_Free(pData);
- }
- FX_DWORD dwSavePos = m_Pos;
- m_Pos += dwStreamSize;
- while (1) {
- FX_DWORD dwPrevPos = m_Pos;
- CPDF_StreamParser::SyntaxType type = ParseNextElement();
- if (type == CPDF_StreamParser::EndOfData) {
- break;
- }
- if (type != CPDF_StreamParser::Keyword) {
- dwStreamSize += m_Pos - dwPrevPos;
- continue;
- }
- if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' &&
- GetWordBuf()[1] == 'I') {
- m_Pos = dwPrevPos;
- break;
- }
- dwStreamSize += m_Pos - dwPrevPos;
- }
- m_Pos = dwSavePos;
- pData = FX_Alloc(FX_BYTE, dwStreamSize);
- FXSYS_memcpy32(pData, m_pBuf + m_Pos, dwStreamSize);
- m_Pos += dwStreamSize;
- }
- }
- pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize);
- return CPDF_Stream::Create(pData, dwStreamSize, pDict);
-}
-#define MAX_WORD_BUFFER 256
-#define MAX_STRING_LENGTH 32767
-#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274)
-#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e)
-#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166)
-CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement()
-{
- if (m_pLastObj) {
- m_pLastObj->Release();
- m_pLastObj = NULL;
- }
- m_WordSize = 0;
- FX_BOOL bIsNumber = TRUE;
- if (m_Pos >= m_Size) {
- return EndOfData;
- }
- int ch = m_pBuf[m_Pos++];
- int type = _PDF_CharType[ch];
- while (1) {
- while (type == 'W') {
- if (m_Size <= m_Pos) {
- return EndOfData;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- if (ch != '%') {
- break;
- }
- while (1) {
- if (m_Size <= m_Pos) {
- return EndOfData;
- }
- ch = m_pBuf[m_Pos++];
- if (ch == '\r' || ch == '\n') {
- break;
- }
- }
- type = _PDF_CharType[ch];
- }
- if (type == 'D' && ch != '/') {
- m_Pos --;
- m_pLastObj = ReadNextObject();
- return Others;
- }
- while (1) {
- if (m_WordSize < MAX_WORD_BUFFER) {
- m_WordBuffer[m_WordSize++] = ch;
- }
- if (type != 'N') {
- bIsNumber = FALSE;
- }
- if (m_Size <= m_Pos) {
- break;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- if (type == 'D' || type == 'W') {
- m_Pos --;
- break;
- }
- }
- m_WordBuffer[m_WordSize] = 0;
- if (bIsNumber) {
- return Number;
- }
- if (m_WordBuffer[0] == '/') {
- return Name;
- }
- if (m_WordSize == 4) {
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) {
- m_pLastObj = CPDF_Boolean::Create(TRUE);
- return Others;
- }
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) {
- m_pLastObj = CPDF_Null::Create();
- return Others;
- }
- } else if (m_WordSize == 5) {
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') {
- m_pLastObj = CPDF_Boolean::Create(FALSE);
- return Others;
- }
- }
- return Keyword;
-}
-void CPDF_StreamParser::SkipPathObject()
-{
- FX_DWORD command_startpos = m_Pos;
- if (m_Pos >= m_Size) {
- return;
- }
- int ch = m_pBuf[m_Pos++];
- int type = _PDF_CharType[ch];
- while (1) {
- while (type == 'W') {
- if (m_Pos >= m_Size) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- if (type != 'N') {
- m_Pos = command_startpos;
- return;
- }
- while (1) {
- while (type != 'W') {
- if (m_Pos >= m_Size) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- while (type == 'W') {
- if (m_Pos >= m_Size) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- if (type == 'N') {
- continue;
- }
- FX_DWORD op_startpos = m_Pos - 1;
- while (type != 'W' && type != 'D') {
- if (m_Pos >= m_Size) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- if (m_Pos - op_startpos == 2) {
- int op = m_pBuf[op_startpos];
- if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y') {
- command_startpos = m_Pos;
- break;
- }
- } else if (m_Pos - op_startpos == 3) {
- if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e') {
- command_startpos = m_Pos;
- break;
- }
- }
- m_Pos = command_startpos;
- return;
- }
- }
-}
-CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOOL bInArray)
-{
- FX_BOOL bIsNumber;
- GetNextWord(bIsNumber);
- if (m_WordSize == 0) {
- return NULL;
- }
- if (bIsNumber) {
- m_WordBuffer[m_WordSize] = 0;
- return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize));
- }
- int first_char = m_WordBuffer[0];
- if (first_char == '/') {
- return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
- }
- if (first_char == '(') {
- return CPDF_String::Create(ReadString());
- }
- if (first_char == '<') {
- if (m_WordSize == 1) {
- return CPDF_String::Create(ReadHexString(), TRUE);
- }
- CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
- while (1) {
- GetNextWord(bIsNumber);
- if (m_WordSize == 0) {
- pDict->Release();
- return NULL;
- }
- if (m_WordSize == 2 && m_WordBuffer[0] == '>') {
- break;
- }
- if (m_WordBuffer[0] != '/') {
- pDict->Release();
- return NULL;
- }
- CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
- CPDF_Object* pObj = ReadNextObject(TRUE);
- if (pObj == NULL) {
- if (pDict) {
- pDict->Release();
- }
- return NULL;
- }
- if (!key.IsEmpty()) {
- pDict->SetAt(key, pObj);
- } else {
- pObj->Release();
- }
- }
- return pDict;
- }
- if (first_char == '[') {
- if (!bAllowNestedArray && bInArray) {
- return NULL;
- }
- CPDF_Array* pArray = CPDF_Array::Create();
- while (1) {
- CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE);
- if (pObj == NULL) {
- if (m_WordSize == 0 || m_WordBuffer[0] == ']') {
- return pArray;
- }
- if (m_WordBuffer[0] == '[') {
- continue;
- }
- } else {
- pArray->Add(pObj);
- }
- }
- }
- if (m_WordSize == 4) {
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) {
- return CPDF_Boolean::Create(TRUE);
- }
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) {
- return CPDF_Null::Create();
- }
- } else if (m_WordSize == 5) {
- if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') {
- return CPDF_Boolean::Create(FALSE);
- }
- }
- return NULL;
-}
-void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber)
-{
- m_WordSize = 0;
- bIsNumber = TRUE;
- if (m_Size <= m_Pos) {
- return;
- }
- int ch = m_pBuf[m_Pos++];
- int type = _PDF_CharType[ch];
- while (1) {
- while (type == 'W') {
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- }
- if (ch != '%') {
- break;
- }
- while (1) {
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- if (ch == '\r' || ch == '\n') {
- break;
- }
- }
- type = _PDF_CharType[ch];
- }
- if (type == 'D') {
- bIsNumber = FALSE;
- m_WordBuffer[m_WordSize++] = ch;
- if (ch == '/') {
- while (1) {
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- if (type != 'R' && type != 'N') {
- m_Pos --;
- return;
- }
- if (m_WordSize < MAX_WORD_BUFFER) {
- m_WordBuffer[m_WordSize++] = ch;
- }
- }
- } else if (ch == '<') {
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- if (ch == '<') {
- m_WordBuffer[m_WordSize++] = ch;
- } else {
- m_Pos --;
- }
- } else if (ch == '>') {
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- if (ch == '>') {
- m_WordBuffer[m_WordSize++] = ch;
- } else {
- m_Pos --;
- }
- }
- return;
- }
- while (1) {
- if (m_WordSize < MAX_WORD_BUFFER) {
- m_WordBuffer[m_WordSize++] = ch;
- }
- if (type != 'N') {
- bIsNumber = FALSE;
- }
- if (m_Size <= m_Pos) {
- return;
- }
- ch = m_pBuf[m_Pos++];
- type = _PDF_CharType[ch];
- if (type == 'D' || type == 'W') {
- m_Pos --;
- break;
- }
- }
-}
-CFX_ByteString CPDF_StreamParser::ReadString()
-{
- if (m_Size <= m_Pos) {
- return CFX_ByteString();
- }
- int ch = m_pBuf[m_Pos++];
- CFX_ByteTextBuf buf;
- int parlevel = 0;
- int status = 0, iEscCode = 0;
- while (1) {
- switch (status) {
- case 0:
- if (ch == ')') {
- if (parlevel == 0) {
- if (buf.GetLength() > MAX_STRING_LENGTH) {
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
- }
- return buf.GetByteString();
- }
- parlevel --;
- buf.AppendChar(')');
- } else if (ch == '(') {
- parlevel ++;
- buf.AppendChar('(');
- } else if (ch == '\\') {
- status = 1;
- } else {
- buf.AppendChar((char)ch);
- }
- break;
- case 1:
- if (ch >= '0' && ch <= '7') {
- iEscCode = ch - '0';
- status = 2;
- break;
- }
- if (ch == 'n') {
- buf.AppendChar('\n');
- } else if (ch == 'r') {
- buf.AppendChar('\r');
- } else if (ch == 't') {
- buf.AppendChar('\t');
- } else if (ch == 'b') {
- buf.AppendChar('\b');
- } else if (ch == 'f') {
- buf.AppendChar('\f');
- } else if (ch == '\r') {
- status = 4;
- break;
- } else if (ch == '\n') {
- } else {
- buf.AppendChar(ch);
- }
- status = 0;
- break;
- case 2:
- if (ch >= '0' && ch <= '7') {
- iEscCode = iEscCode * 8 + ch - '0';
- status = 3;
- } else {
- buf.AppendChar(iEscCode);
- status = 0;
- continue;
- }
- break;
- case 3:
- if (ch >= '0' && ch <= '7') {
- iEscCode = iEscCode * 8 + ch - '0';
- buf.AppendChar(iEscCode);
- status = 0;
- } else {
- buf.AppendChar(iEscCode);
- status = 0;
- continue;
- }
- break;
- case 4:
- status = 0;
- if (ch != '\n') {
- continue;
- }
- break;
- }
- if (m_Size <= m_Pos) {
- break;
- }
- ch = m_pBuf[m_Pos++];
- }
- if (m_Size > m_Pos) {
- ch = m_pBuf[m_Pos++];
- }
- if (buf.GetLength() > MAX_STRING_LENGTH) {
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
- }
- return buf.GetByteString();
-}
-CFX_ByteString CPDF_StreamParser::ReadHexString()
-{
- if (m_Size <= m_Pos) {
- return CFX_ByteString();
- }
- int ch = m_pBuf[m_Pos++];
- CFX_ByteTextBuf buf;
- FX_BOOL bFirst = TRUE;
- int code = 0;
- while (1) {
- if (ch == '>') {
- break;
- }
- if (ch >= '0' && ch <= '9') {
- if (bFirst) {
- code = (ch - '0') * 16;
- } else {
- code += ch - '0';
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- } else if (ch >= 'A' && ch <= 'F') {
- if (bFirst) {
- code = (ch - 'A' + 10) * 16;
- } else {
- code += ch - 'A' + 10;
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- } else if (ch >= 'a' && ch <= 'f') {
- if (bFirst) {
- code = (ch - 'a' + 10) * 16;
- } else {
- code += ch - 'a' + 10;
- buf.AppendChar((char)code);
- }
- bFirst = !bFirst;
- }
- if (m_Size <= m_Pos) {
- break;
- }
- ch = m_pBuf[m_Pos++];
- }
- if (!bFirst) {
- buf.AppendChar((char)code);
- }
- if (buf.GetLength() > MAX_STRING_LENGTH) {
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
- }
- return buf.GetByteString();
-}
-#define PAGEPARSE_STAGE_GETCONTENT 1
-#define PAGEPARSE_STAGE_PARSE 2
-#define PAGEPARSE_STAGE_CHECKCLIP 3
-CPDF_ContentParser::CPDF_ContentParser()
-{
- m_pParser = NULL;
- m_pStreamArray = NULL;
- m_pSingleStream = NULL;
- m_pData = NULL;
- m_Status = Ready;
- m_pType3Char = NULL;
-}
-CPDF_ContentParser::~CPDF_ContentParser()
-{
- Clear();
-}
-void CPDF_ContentParser::Clear()
-{
- if (m_pParser) {
- delete m_pParser;
- }
- if (m_pSingleStream) {
- delete m_pSingleStream;
- }
- if (m_pStreamArray) {
- for (FX_DWORD i = 0; i < m_nStreams; i ++)
- if (m_pStreamArray[i]) {
- delete m_pStreamArray[i];
- }
- FX_Free(m_pStreamArray);
- }
- if (m_pData && m_pSingleStream == NULL) {
- FX_Free((void*)m_pData);
- }
- m_pParser = NULL;
- m_pStreamArray = NULL;
- m_pSingleStream = NULL;
- m_pData = NULL;
- m_Status = Ready;
-}
-void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions)
-{
- if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) {
- m_Status = Done;
- return;
- }
- m_pObjects = pPage;
- m_bForm = FALSE;
- if (pOptions) {
- m_Options = *pOptions;
- }
- m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_GETCONTENT;
- m_CurrentOffset = 0;
- CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
- if (pContent == NULL) {
- m_Status = Done;
- return;
- }
- if (pContent->GetType() == PDFOBJ_STREAM) {
- m_nStreams = 0;
- m_pSingleStream = FX_NEW CPDF_StreamAcc;
- m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE);
- } else if (pContent->GetType() == PDFOBJ_ARRAY) {
- CPDF_Array* pArray = (CPDF_Array*)pContent;
- m_nStreams = pArray->GetCount();
- if (m_nStreams == 0) {
- m_Status = Done;
- return;
- }
- m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams);
- FXSYS_memset32(m_pStreamArray, 0, sizeof(CPDF_StreamAcc*) * m_nStreams);
- } else {
- m_Status = Done;
- return;
- }
-}
-void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates,
- CFX_AffineMatrix* pParentMatrix, CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
-{
- m_pType3Char = pType3Char;
- m_pObjects = pForm;
- m_bForm = TRUE;
- CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix"));
- if (pGraphicStates) {
- form_matrix.Concat(pGraphicStates->m_CTM);
- }
- CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox"));
- CFX_FloatRect form_bbox;
- CPDF_Path ClipPath;
- if (pBBox) {
- form_bbox = pBBox->GetRect();
- ClipPath.New();
- ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top);
- ClipPath.Transform(&form_matrix);
- if (pParentMatrix) {
- ClipPath.Transform(pParentMatrix);
- }
- form_bbox.Transform(&form_matrix);
- if (pParentMatrix) {
- form_bbox.Transform(pParentMatrix);
- }
- }
- CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
- m_pParser = FX_NEW CPDF_StreamContentParser;
- m_pParser->Initialize();
- m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm,
- pResources, &form_bbox, pOptions, pGraphicStates, level);
- m_pParser->m_pCurStates->m_CTM = form_matrix;
- m_pParser->m_pCurStates->m_ParentMatrix = form_matrix;
- if (ClipPath.NotNull()) {
- m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE);
- }
- if (pForm->m_Transparency & PDFTRANS_GROUP) {
- CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify();
- pData->m_BlendType = FXDIB_BLEND_NORMAL;
- pData->m_StrokeAlpha = 1.0f;
- pData->m_FillAlpha = 1.0f;
- pData->m_pSoftMask = NULL;
- }
- m_nStreams = 0;
- m_pSingleStream = FX_NEW CPDF_StreamAcc;
- if (pForm->m_pDocument) {
- m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE);
- } else {
- m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE);
- }
- m_pData = (FX_LPBYTE)m_pSingleStream->GetData();
- m_Size = m_pSingleStream->GetSize();
- m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
- m_CurrentOffset = 0;
-}
-void CPDF_ContentParser::Continue(IFX_Pause* pPause)
-{
- int steps = 0;
- while (m_Status == ToBeContinued) {
- if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) {
- if (m_CurrentOffset == m_nStreams) {
- if (m_pStreamArray) {
- m_Size = 0;
- FX_DWORD i;
- for (i = 0; i < m_nStreams; i ++) {
- FX_DWORD size = m_pStreamArray[i]->GetSize();
- if (m_Size + size + 1 <= m_Size) {
- m_Status = Done;
- return;
- }
- m_Size += size + 1;
- }
- m_pData = FX_Alloc(FX_BYTE, m_Size);
- if (!m_pData) {
- m_Status = Done;
- return;
- }
- FX_DWORD pos = 0;
- for (i = 0; i < m_nStreams; i ++) {
- FXSYS_memcpy32(m_pData + pos, m_pStreamArray[i]->GetData(), m_pStreamArray[i]->GetSize());
- pos += m_pStreamArray[i]->GetSize() + 1;
- m_pData[pos - 1] = ' ';
- delete m_pStreamArray[i];
- }
- FX_Free(m_pStreamArray);
- m_pStreamArray = NULL;
- } else {
- m_pData = (FX_LPBYTE)m_pSingleStream->GetData();
- m_Size = m_pSingleStream->GetSize();
- }
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
- m_CurrentOffset = 0;
- } else {
- CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArray(FX_BSTRC("Contents"));
- m_pStreamArray[m_CurrentOffset] = FX_NEW CPDF_StreamAcc;
- CPDF_Stream* pStreamObj = (CPDF_Stream*)pContent->GetElementValue(m_CurrentOffset);
- m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE);
- m_CurrentOffset ++;
- }
- }
- if (m_InternalStage == PAGEPARSE_STAGE_PARSE) {
- if (m_pParser == NULL) {
- m_pParser = FX_NEW CPDF_StreamContentParser;
- m_pParser->Initialize();
- m_pParser->PrepareParse(m_pObjects->m_pDocument, m_pObjects->m_pPageResources, NULL, NULL, m_pObjects,
- m_pObjects->m_pResources, &m_pObjects->m_BBox, &m_Options, NULL, 0);
- m_pParser->m_pCurStates->m_ColorState.GetModify()->Default();
- }
- if (m_CurrentOffset >= m_Size) {
- m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
- } else {
- m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m_Size - m_CurrentOffset, PARSE_STEP_LIMIT);
- if (m_pParser->m_bAbort) {
- m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
- continue;
- }
- }
- }
- if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
- if (m_pType3Char) {
- m_pType3Char->m_bColored = m_pParser->m_bColored;
- m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000);
- m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000);
- m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000);
- m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000);
- m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000);
- }
- FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition();
- while (pos) {
- CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos);
- if (pObj->m_ClipPath.IsNull()) {
- continue;
- }
- if (pObj->m_ClipPath.GetPathCount() != 1) {
- continue;
- }
- if (pObj->m_ClipPath.GetTextCount()) {
- continue;
- }
- CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
- if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) {
- continue;
- }
- CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
- ClipPath.GetPointX(2), ClipPath.GetPointY(2));
- CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
- if (old_rect.Contains(obj_rect)) {
- pObj->m_ClipPath.SetNull();
- }
- }
- m_Status = Done;
- return;
- }
- steps ++;
- if (pPause && pPause->NeedToPauseNow()) {
- break;
- }
- }
-}
-int CPDF_ContentParser::EstimateProgress()
-{
- if (m_Status == Ready) {
- return 0;
- }
- if (m_Status == Done) {
- return 100;
- }
- if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) {
- return 10;
- }
- if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
- return 90;
- }
- return 10 + 80 * m_CurrentOffset / m_Size;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "../../../include/fxcodec/fx_codec.h" +#include "pageint.h" +#include <limits.h> +extern const FX_LPCSTR _PDF_OpCharType = + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII" + "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII" + "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"; +FX_BOOL _PDF_HasInvalidOpChar(FX_LPCSTR op) +{ + if(!op) { + return FALSE; + } + FX_BYTE ch; + while((ch = *op++)) { + if(_PDF_OpCharType[ch] == 'I') { + return TRUE; + } + } + return FALSE; +} +FX_DWORD CPDF_StreamContentParser::Parse(FX_LPCBYTE pData, FX_DWORD dwSize, FX_DWORD max_cost) +{ + if (m_Level > _FPDF_MAX_FORM_LEVEL_) { + return dwSize; + } + FX_DWORD InitObjCount = m_pObjectList->CountObjects(); + CPDF_StreamParser syntax(pData, dwSize); + m_pSyntax = &syntax; + m_CompatCount = 0; + while (1) { + FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount; + if (max_cost && cost >= max_cost) { + break; + } + switch (syntax.ParseNextElement()) { + case CPDF_StreamParser::EndOfData: + return m_pSyntax->GetPos(); + case CPDF_StreamParser::Keyword: + if(!OnOperator((char*)syntax.GetWordBuf()) && _PDF_HasInvalidOpChar((char*)syntax.GetWordBuf())) { + m_bAbort = TRUE; + } + if (m_bAbort) { + return m_pSyntax->GetPos(); + } + ClearAllParams(); + break; + case CPDF_StreamParser::Number: + AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); + break; + case CPDF_StreamParser::Name: + AddNameParam((FX_LPCSTR)syntax.GetWordBuf() + 1, syntax.GetWordSize() - 1); + break; + default: + AddObjectParam(syntax.GetObject()); + } + } + return m_pSyntax->GetPos(); +} +void _PDF_ReplaceAbbr(CPDF_Object* pObj); +void CPDF_StreamContentParser::Handle_BeginImage() +{ + FX_FILESIZE savePos = m_pSyntax->GetPos(); + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + if (type == CPDF_StreamParser::Keyword) { + CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()); + if (bsKeyword != FX_BSTRC("ID")) { + m_pSyntax->SetPos(savePos); + pDict->Release(); + return; + } + } + if (type != CPDF_StreamParser::Name) { + break; + } + CFX_ByteString key((FX_LPCSTR)m_pSyntax->GetWordBuf() + 1, m_pSyntax->GetWordSize() - 1); + CPDF_Object* pObj = m_pSyntax->ReadNextObject(); + if (!key.IsEmpty()) { + pDict->SetAt(key, pObj, m_pDocument); + } else { + pObj->Release(); + } + } + _PDF_ReplaceAbbr(pDict); + CPDF_Object* pCSObj = NULL; + if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) { + pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj->GetType() == PDFOBJ_NAME) { + CFX_ByteString name = pCSObj->GetString(); + if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) { + pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); + if (pCSObj && !pCSObj->GetObjNum()) { + pCSObj = pCSObj->Clone(); + pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); + } + } + } + } + CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + if (type == CPDF_StreamParser::EndOfData) { + break; + } + if (type != CPDF_StreamParser::Keyword) { + continue; + } + if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && + m_pSyntax->GetWordBuf()[1] == 'I') { + break; + } + } + if (m_Options.m_bTextOnly) { + if (pStream) { + pStream->Release(); + } else { + pDict->Release(); + } + return; + } + pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); + CPDF_ImageObject *pImgObj = AddImage(pStream, NULL, TRUE); + if (!pImgObj) { + if (pStream) { + pStream->Release(); + } else { + pDict->Release(); + } + } +} +void CPDF_StreamContentParser::ParsePathObject() +{ + FX_FLOAT params[6] = {0}; + int nParams = 0; + int last_pos = m_pSyntax->GetPos(); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + FX_BOOL bProcessed = TRUE; + switch (type) { + case CPDF_StreamParser::EndOfData: + return; + case CPDF_StreamParser::Keyword: { + int len = m_pSyntax->GetWordSize(); + if (len == 1) { + switch (m_pSyntax->GetWordBuf()[0]) { + case 'm': + AddPathPoint(params[0], params[1], FXPT_MOVETO); + nParams = 0; + break; + case 'l': + AddPathPoint(params[0], params[1], FXPT_LINETO); + nParams = 0; + break; + case 'c': + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + AddPathPoint(params[4], params[5], FXPT_BEZIERTO); + nParams = 0; + break; + case 'v': + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + nParams = 0; + break; + case 'y': + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + nParams = 0; + break; + case 'h': + Handle_ClosePath(); + nParams = 0; + break; + default: + bProcessed = FALSE; + break; + } + } else if (len == 2) { + if (m_pSyntax->GetWordBuf()[0] == 'r' && m_pSyntax->GetWordBuf()[1] == 'e') { + AddPathRect(params[0], params[1], params[2], params[3]); + nParams = 0; + } else { + bProcessed = FALSE; + } + } else { + bProcessed = FALSE; + } + if (bProcessed) { + last_pos = m_pSyntax->GetPos(); + } + break; + } + case CPDF_StreamParser::Number: { + if (nParams == 6) { + break; + } + FX_BOOL bInteger; + int value; + FX_atonum(CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), bInteger, &value); + params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; + break; + } + default: + bProcessed = FALSE; + } + if (!bProcessed) { + m_pSyntax->SetPos(last_pos); + return; + } + } +} +CPDF_StreamParser::CPDF_StreamParser(const FX_BYTE* pData, FX_DWORD dwSize) +{ + m_pBuf = pData; + m_Size = dwSize; + m_Pos = 0; + m_pLastObj = NULL; +} +CPDF_StreamParser::~CPDF_StreamParser() +{ + if (m_pLastObj) { + m_pLastObj->Release(); + } +} +FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) +{ + if (pDecoder == NULL) { + return (FX_DWORD) - 1; + } + int ncomps = pDecoder->CountComps(); + int bpc = pDecoder->GetBPC(); + int width = pDecoder->GetWidth(); + int height = pDecoder->GetHeight(); + int pitch = (width * ncomps * bpc + 7) / 8; + if (height == 0 || pitch > (1 << 30) / height) { + delete pDecoder; + return -1; + } + dest_size = pitch * height; + dest_buf = FX_Alloc( FX_BYTE, dest_size); + for (int row = 0; row < height; row ++) { + FX_LPBYTE pLine = pDecoder->GetScanline(row); + if (pLine == NULL) { + break; + } + FXSYS_memcpy32(dest_buf + row * pitch, pLine, pitch); + } + FX_DWORD srcoff = pDecoder->GetSrcOffset(); + delete pDecoder; + return srcoff; +} +ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, + const CPDF_Dictionary* pParams); +FX_DWORD _A85Decode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size); +FX_DWORD _HexDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size); +FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams, + FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size); +FX_DWORD PDF_DecodeInlineStream(const FX_BYTE* src_buf, FX_DWORD limit, + int width, int height, CFX_ByteString& decoder, + CPDF_Dictionary* pParam, FX_LPBYTE& dest_buf, FX_DWORD& dest_size) +{ + if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) { + ICodec_ScanlineDecoder* pDecoder = FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); + return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { + return _A85Decode(src_buf, limit, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { + return _HexDecode(src_buf, limit, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { + return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { + return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) { + ICodec_ScanlineDecoder* pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( + src_buf, limit, width, height, 0, pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); + return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); + } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { + return RunLengthDecode(src_buf, limit, dest_buf, dest_size); + } + dest_size = 0; + dest_buf = 0; + return (FX_DWORD) - 1; +} +extern const FX_LPCSTR _PDF_CharType; +CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode) +{ + if (m_Pos == m_Size) { + return NULL; + } + if (_PDF_CharType[m_pBuf[m_Pos]] == 'W') { + m_Pos ++; + } + CFX_ByteString Decoder; + CPDF_Dictionary* pParam = NULL; + CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); + if (pFilter == NULL) { + } else if (pFilter->GetType() == PDFOBJ_ARRAY) { + Decoder = ((CPDF_Array*)pFilter)->GetString(0); + CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); + if (pParams) { + pParam = pParams->GetDict(0); + } + } else { + Decoder = pFilter->GetString(); + pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); + } + FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); + FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); + FX_DWORD OrigSize = 0; + if (pCSObj != NULL) { + FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); + FX_DWORD nComponents = 1; + CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); + if (pCS == NULL) { + nComponents = 3; + } else { + nComponents = pCS->CountComponents(); + pDoc->GetPageData()->ReleaseColorSpace(pCSObj); + } + FX_DWORD pitch = width; + if (bpc && pitch > INT_MAX / bpc) { + return NULL; + } + pitch *= bpc; + if (nComponents && pitch > INT_MAX / nComponents) { + return NULL; + } + pitch *= nComponents; + if (pitch > INT_MAX - 7) { + return NULL; + } + pitch += 7; + pitch /= 8; + OrigSize = pitch; + } else { + if (width > INT_MAX - 7) { + return NULL; + } + OrigSize = ((width + 7) / 8); + } + if (height && OrigSize > INT_MAX / height) { + return NULL; + } + OrigSize *= height; + FX_LPBYTE pData = NULL; + FX_DWORD dwStreamSize; + if (Decoder.IsEmpty()) { + if (OrigSize > m_Size - m_Pos) { + OrigSize = m_Size - m_Pos; + } + pData = FX_Alloc(FX_BYTE, OrigSize); + FXSYS_memcpy32(pData, m_pBuf + m_Pos, OrigSize); + dwStreamSize = OrigSize; + m_Pos += OrigSize; + } else { + FX_DWORD dwDestSize = OrigSize; + dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, Decoder, pParam, + pData, dwDestSize); + if ((int)dwStreamSize < 0) { + return NULL; + } + if (bDecode) { + m_Pos += dwStreamSize; + dwStreamSize = dwDestSize; + if (pFilter->GetType() == PDFOBJ_ARRAY) { + ((CPDF_Array*)pFilter)->RemoveAt(0); + CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); + if (pParams) { + pParams->RemoveAt(0); + } + } else { + pDict->RemoveAt(FX_BSTRC("Filter")); + pDict->RemoveAt(FX_BSTRC("DecodeParms")); + } + } else { + if (pData) { + FX_Free(pData); + } + FX_DWORD dwSavePos = m_Pos; + m_Pos += dwStreamSize; + while (1) { + FX_DWORD dwPrevPos = m_Pos; + CPDF_StreamParser::SyntaxType type = ParseNextElement(); + if (type == CPDF_StreamParser::EndOfData) { + break; + } + if (type != CPDF_StreamParser::Keyword) { + dwStreamSize += m_Pos - dwPrevPos; + continue; + } + if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && + GetWordBuf()[1] == 'I') { + m_Pos = dwPrevPos; + break; + } + dwStreamSize += m_Pos - dwPrevPos; + } + m_Pos = dwSavePos; + pData = FX_Alloc(FX_BYTE, dwStreamSize); + FXSYS_memcpy32(pData, m_pBuf + m_Pos, dwStreamSize); + m_Pos += dwStreamSize; + } + } + pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); + return CPDF_Stream::Create(pData, dwStreamSize, pDict); +} +#define MAX_WORD_BUFFER 256 +#define MAX_STRING_LENGTH 32767 +#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) +#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) +#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) +CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() +{ + if (m_pLastObj) { + m_pLastObj->Release(); + m_pLastObj = NULL; + } + m_WordSize = 0; + FX_BOOL bIsNumber = TRUE; + if (m_Pos >= m_Size) { + return EndOfData; + } + int ch = m_pBuf[m_Pos++]; + int type = _PDF_CharType[ch]; + while (1) { + while (type == 'W') { + if (m_Size <= m_Pos) { + return EndOfData; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + if (ch != '%') { + break; + } + while (1) { + if (m_Size <= m_Pos) { + return EndOfData; + } + ch = m_pBuf[m_Pos++]; + if (ch == '\r' || ch == '\n') { + break; + } + } + type = _PDF_CharType[ch]; + } + if (type == 'D' && ch != '/') { + m_Pos --; + m_pLastObj = ReadNextObject(); + return Others; + } + while (1) { + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; + } + if (type != 'N') { + bIsNumber = FALSE; + } + if (m_Size <= m_Pos) { + break; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + if (type == 'D' || type == 'W') { + m_Pos --; + break; + } + } + m_WordBuffer[m_WordSize] = 0; + if (bIsNumber) { + return Number; + } + if (m_WordBuffer[0] == '/') { + return Name; + } + if (m_WordSize == 4) { + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { + m_pLastObj = CPDF_Boolean::Create(TRUE); + return Others; + } + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { + m_pLastObj = CPDF_Null::Create(); + return Others; + } + } else if (m_WordSize == 5) { + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { + m_pLastObj = CPDF_Boolean::Create(FALSE); + return Others; + } + } + return Keyword; +} +void CPDF_StreamParser::SkipPathObject() +{ + FX_DWORD command_startpos = m_Pos; + if (m_Pos >= m_Size) { + return; + } + int ch = m_pBuf[m_Pos++]; + int type = _PDF_CharType[ch]; + while (1) { + while (type == 'W') { + if (m_Pos >= m_Size) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + if (type != 'N') { + m_Pos = command_startpos; + return; + } + while (1) { + while (type != 'W') { + if (m_Pos >= m_Size) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + while (type == 'W') { + if (m_Pos >= m_Size) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + if (type == 'N') { + continue; + } + FX_DWORD op_startpos = m_Pos - 1; + while (type != 'W' && type != 'D') { + if (m_Pos >= m_Size) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + if (m_Pos - op_startpos == 2) { + int op = m_pBuf[op_startpos]; + if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y') { + command_startpos = m_Pos; + break; + } + } else if (m_Pos - op_startpos == 3) { + if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e') { + command_startpos = m_Pos; + break; + } + } + m_Pos = command_startpos; + return; + } + } +} +CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOOL bInArray) +{ + FX_BOOL bIsNumber; + GetNextWord(bIsNumber); + if (m_WordSize == 0) { + return NULL; + } + if (bIsNumber) { + m_WordBuffer[m_WordSize] = 0; + return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); + } + int first_char = m_WordBuffer[0]; + if (first_char == '/') { + return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + } + if (first_char == '(') { + return CPDF_String::Create(ReadString()); + } + if (first_char == '<') { + if (m_WordSize == 1) { + return CPDF_String::Create(ReadHexString(), TRUE); + } + CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); + while (1) { + GetNextWord(bIsNumber); + if (m_WordSize == 0) { + pDict->Release(); + return NULL; + } + if (m_WordSize == 2 && m_WordBuffer[0] == '>') { + break; + } + if (m_WordBuffer[0] != '/') { + pDict->Release(); + return NULL; + } + CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); + CPDF_Object* pObj = ReadNextObject(TRUE); + if (pObj == NULL) { + if (pDict) { + pDict->Release(); + } + return NULL; + } + if (!key.IsEmpty()) { + pDict->SetAt(key, pObj); + } else { + pObj->Release(); + } + } + return pDict; + } + if (first_char == '[') { + if (!bAllowNestedArray && bInArray) { + return NULL; + } + CPDF_Array* pArray = CPDF_Array::Create(); + while (1) { + CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); + if (pObj == NULL) { + if (m_WordSize == 0 || m_WordBuffer[0] == ']') { + return pArray; + } + if (m_WordBuffer[0] == '[') { + continue; + } + } else { + pArray->Add(pObj); + } + } + } + if (m_WordSize == 4) { + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { + return CPDF_Boolean::Create(TRUE); + } + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { + return CPDF_Null::Create(); + } + } else if (m_WordSize == 5) { + if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { + return CPDF_Boolean::Create(FALSE); + } + } + return NULL; +} +void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) +{ + m_WordSize = 0; + bIsNumber = TRUE; + if (m_Size <= m_Pos) { + return; + } + int ch = m_pBuf[m_Pos++]; + int type = _PDF_CharType[ch]; + while (1) { + while (type == 'W') { + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + } + if (ch != '%') { + break; + } + while (1) { + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + if (ch == '\r' || ch == '\n') { + break; + } + } + type = _PDF_CharType[ch]; + } + if (type == 'D') { + bIsNumber = FALSE; + m_WordBuffer[m_WordSize++] = ch; + if (ch == '/') { + while (1) { + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + if (type != 'R' && type != 'N') { + m_Pos --; + return; + } + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; + } + } + } else if (ch == '<') { + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + if (ch == '<') { + m_WordBuffer[m_WordSize++] = ch; + } else { + m_Pos --; + } + } else if (ch == '>') { + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + if (ch == '>') { + m_WordBuffer[m_WordSize++] = ch; + } else { + m_Pos --; + } + } + return; + } + while (1) { + if (m_WordSize < MAX_WORD_BUFFER) { + m_WordBuffer[m_WordSize++] = ch; + } + if (type != 'N') { + bIsNumber = FALSE; + } + if (m_Size <= m_Pos) { + return; + } + ch = m_pBuf[m_Pos++]; + type = _PDF_CharType[ch]; + if (type == 'D' || type == 'W') { + m_Pos --; + break; + } + } +} +CFX_ByteString CPDF_StreamParser::ReadString() +{ + if (m_Size <= m_Pos) { + return CFX_ByteString(); + } + int ch = m_pBuf[m_Pos++]; + CFX_ByteTextBuf buf; + int parlevel = 0; + int status = 0, iEscCode = 0; + while (1) { + switch (status) { + case 0: + if (ch == ')') { + if (parlevel == 0) { + if (buf.GetLength() > MAX_STRING_LENGTH) { + return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); + } + return buf.GetByteString(); + } + parlevel --; + buf.AppendChar(')'); + } else if (ch == '(') { + parlevel ++; + buf.AppendChar('('); + } else if (ch == '\\') { + status = 1; + } else { + buf.AppendChar((char)ch); + } + break; + case 1: + if (ch >= '0' && ch <= '7') { + iEscCode = ch - '0'; + status = 2; + break; + } + if (ch == 'n') { + buf.AppendChar('\n'); + } else if (ch == 'r') { + buf.AppendChar('\r'); + } else if (ch == 't') { + buf.AppendChar('\t'); + } else if (ch == 'b') { + buf.AppendChar('\b'); + } else if (ch == 'f') { + buf.AppendChar('\f'); + } else if (ch == '\r') { + status = 4; + break; + } else if (ch == '\n') { + } else { + buf.AppendChar(ch); + } + status = 0; + break; + case 2: + if (ch >= '0' && ch <= '7') { + iEscCode = iEscCode * 8 + ch - '0'; + status = 3; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; + } + break; + case 3: + if (ch >= '0' && ch <= '7') { + iEscCode = iEscCode * 8 + ch - '0'; + buf.AppendChar(iEscCode); + status = 0; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; + } + break; + case 4: + status = 0; + if (ch != '\n') { + continue; + } + break; + } + if (m_Size <= m_Pos) { + break; + } + ch = m_pBuf[m_Pos++]; + } + if (m_Size > m_Pos) { + ch = m_pBuf[m_Pos++]; + } + if (buf.GetLength() > MAX_STRING_LENGTH) { + return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); + } + return buf.GetByteString(); +} +CFX_ByteString CPDF_StreamParser::ReadHexString() +{ + if (m_Size <= m_Pos) { + return CFX_ByteString(); + } + int ch = m_pBuf[m_Pos++]; + CFX_ByteTextBuf buf; + FX_BOOL bFirst = TRUE; + int code = 0; + while (1) { + if (ch == '>') { + break; + } + if (ch >= '0' && ch <= '9') { + if (bFirst) { + code = (ch - '0') * 16; + } else { + code += ch - '0'; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } else if (ch >= 'A' && ch <= 'F') { + if (bFirst) { + code = (ch - 'A' + 10) * 16; + } else { + code += ch - 'A' + 10; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } else if (ch >= 'a' && ch <= 'f') { + if (bFirst) { + code = (ch - 'a' + 10) * 16; + } else { + code += ch - 'a' + 10; + buf.AppendChar((char)code); + } + bFirst = !bFirst; + } + if (m_Size <= m_Pos) { + break; + } + ch = m_pBuf[m_Pos++]; + } + if (!bFirst) { + buf.AppendChar((char)code); + } + if (buf.GetLength() > MAX_STRING_LENGTH) { + return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); + } + return buf.GetByteString(); +} +#define PAGEPARSE_STAGE_GETCONTENT 1 +#define PAGEPARSE_STAGE_PARSE 2 +#define PAGEPARSE_STAGE_CHECKCLIP 3 +CPDF_ContentParser::CPDF_ContentParser() +{ + m_pParser = NULL; + m_pStreamArray = NULL; + m_pSingleStream = NULL; + m_pData = NULL; + m_Status = Ready; + m_pType3Char = NULL; +} +CPDF_ContentParser::~CPDF_ContentParser() +{ + Clear(); +} +void CPDF_ContentParser::Clear() +{ + if (m_pParser) { + delete m_pParser; + } + if (m_pSingleStream) { + delete m_pSingleStream; + } + if (m_pStreamArray) { + for (FX_DWORD i = 0; i < m_nStreams; i ++) + if (m_pStreamArray[i]) { + delete m_pStreamArray[i]; + } + FX_Free(m_pStreamArray); + } + if (m_pData && m_pSingleStream == NULL) { + FX_Free((void*)m_pData); + } + m_pParser = NULL; + m_pStreamArray = NULL; + m_pSingleStream = NULL; + m_pData = NULL; + m_Status = Ready; +} +void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) +{ + if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) { + m_Status = Done; + return; + } + m_pObjects = pPage; + m_bForm = FALSE; + if (pOptions) { + m_Options = *pOptions; + } + m_Status = ToBeContinued; + m_InternalStage = PAGEPARSE_STAGE_GETCONTENT; + m_CurrentOffset = 0; + CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); + if (pContent == NULL) { + m_Status = Done; + return; + } + if (pContent->GetType() == PDFOBJ_STREAM) { + m_nStreams = 0; + m_pSingleStream = FX_NEW CPDF_StreamAcc; + m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE); + } else if (pContent->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pContent; + m_nStreams = pArray->GetCount(); + if (m_nStreams == 0) { + m_Status = Done; + return; + } + m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams); + FXSYS_memset32(m_pStreamArray, 0, sizeof(CPDF_StreamAcc*) * m_nStreams); + } else { + m_Status = Done; + return; + } +} +void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, + CFX_AffineMatrix* pParentMatrix, CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) +{ + m_pType3Char = pType3Char; + m_pObjects = pForm; + m_bForm = TRUE; + CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix")); + if (pGraphicStates) { + form_matrix.Concat(pGraphicStates->m_CTM); + } + CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); + CFX_FloatRect form_bbox; + CPDF_Path ClipPath; + if (pBBox) { + form_bbox = pBBox->GetRect(); + ClipPath.New(); + ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top); + ClipPath.Transform(&form_matrix); + if (pParentMatrix) { + ClipPath.Transform(pParentMatrix); + } + form_bbox.Transform(&form_matrix); + if (pParentMatrix) { + form_bbox.Transform(pParentMatrix); + } + } + CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + m_pParser = FX_NEW CPDF_StreamContentParser; + m_pParser->Initialize(); + m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm, + pResources, &form_bbox, pOptions, pGraphicStates, level); + m_pParser->m_pCurStates->m_CTM = form_matrix; + m_pParser->m_pCurStates->m_ParentMatrix = form_matrix; + if (ClipPath.NotNull()) { + m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE); + } + if (pForm->m_Transparency & PDFTRANS_GROUP) { + CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify(); + pData->m_BlendType = FXDIB_BLEND_NORMAL; + pData->m_StrokeAlpha = 1.0f; + pData->m_FillAlpha = 1.0f; + pData->m_pSoftMask = NULL; + } + m_nStreams = 0; + m_pSingleStream = FX_NEW CPDF_StreamAcc; + if (pForm->m_pDocument) { + m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); + } else { + m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); + } + m_pData = (FX_LPBYTE)m_pSingleStream->GetData(); + m_Size = m_pSingleStream->GetSize(); + m_Status = ToBeContinued; + m_InternalStage = PAGEPARSE_STAGE_PARSE; + m_CurrentOffset = 0; +} +void CPDF_ContentParser::Continue(IFX_Pause* pPause) +{ + int steps = 0; + while (m_Status == ToBeContinued) { + if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { + if (m_CurrentOffset == m_nStreams) { + if (m_pStreamArray) { + m_Size = 0; + FX_DWORD i; + for (i = 0; i < m_nStreams; i ++) { + FX_DWORD size = m_pStreamArray[i]->GetSize(); + if (m_Size + size + 1 <= m_Size) { + m_Status = Done; + return; + } + m_Size += size + 1; + } + m_pData = FX_Alloc(FX_BYTE, m_Size); + if (!m_pData) { + m_Status = Done; + return; + } + FX_DWORD pos = 0; + for (i = 0; i < m_nStreams; i ++) { + FXSYS_memcpy32(m_pData + pos, m_pStreamArray[i]->GetData(), m_pStreamArray[i]->GetSize()); + pos += m_pStreamArray[i]->GetSize() + 1; + m_pData[pos - 1] = ' '; + delete m_pStreamArray[i]; + } + FX_Free(m_pStreamArray); + m_pStreamArray = NULL; + } else { + m_pData = (FX_LPBYTE)m_pSingleStream->GetData(); + m_Size = m_pSingleStream->GetSize(); + } + m_InternalStage = PAGEPARSE_STAGE_PARSE; + m_CurrentOffset = 0; + } else { + CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArray(FX_BSTRC("Contents")); + m_pStreamArray[m_CurrentOffset] = FX_NEW CPDF_StreamAcc; + CPDF_Stream* pStreamObj = (CPDF_Stream*)pContent->GetElementValue(m_CurrentOffset); + m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); + m_CurrentOffset ++; + } + } + if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { + if (m_pParser == NULL) { + m_pParser = FX_NEW CPDF_StreamContentParser; + m_pParser->Initialize(); + m_pParser->PrepareParse(m_pObjects->m_pDocument, m_pObjects->m_pPageResources, NULL, NULL, m_pObjects, + m_pObjects->m_pResources, &m_pObjects->m_BBox, &m_Options, NULL, 0); + m_pParser->m_pCurStates->m_ColorState.GetModify()->Default(); + } + if (m_CurrentOffset >= m_Size) { + m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; + } else { + m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); + if (m_pParser->m_bAbort) { + m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; + continue; + } + } + } + if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { + if (m_pType3Char) { + m_pType3Char->m_bColored = m_pParser->m_bColored; + m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000); + m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000); + m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000); + m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000); + m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000); + } + FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); + while (pos) { + CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); + if (pObj->m_ClipPath.IsNull()) { + continue; + } + if (pObj->m_ClipPath.GetPathCount() != 1) { + continue; + } + if (pObj->m_ClipPath.GetTextCount()) { + continue; + } + CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); + if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { + continue; + } + CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), + ClipPath.GetPointX(2), ClipPath.GetPointY(2)); + CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); + if (old_rect.Contains(obj_rect)) { + pObj->m_ClipPath.SetNull(); + } + } + m_Status = Done; + return; + } + steps ++; + if (pPause && pPause->NeedToPauseNow()) { + break; + } + } +} +int CPDF_ContentParser::EstimateProgress() +{ + if (m_Status == Ready) { + return 0; + } + if (m_Status == Done) { + return 100; + } + if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { + return 10; + } + if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { + return 90; + } + return 10 + 80 * m_CurrentOffset / m_Size; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_path.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_path.cpp index 836c940f5e..8b4d42236b 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_path.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_path.cpp @@ -1,52 +1,52 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "../../../include/fpdfapi/fpdf_pageobj.h"
-#include "../../../include/fpdfapi/fpdf_module.h"
-#include "pageint.h"
-void CPDF_PathObject::CopyData(const CPDF_PageObject* pSrc)
-{
- const CPDF_PathObject* pSrcObj = (const CPDF_PathObject*)pSrc;
- m_Path = pSrcObj->m_Path;
- m_FillType = pSrcObj->m_FillType;
- m_bStroke = pSrcObj->m_bStroke;
- m_Matrix = pSrcObj->m_Matrix;
-}
-void CPDF_PathObject::Transform(const CPDF_Matrix& matrix)
-{
- m_Matrix.Concat(matrix);
- CalcBoundingBox();
-}
-void CPDF_PathObject::SetGraphState(CPDF_GraphState GraphState)
-{
- m_GraphState = GraphState;
- CalcBoundingBox();
-}
-void CPDF_PathObject::CalcBoundingBox()
-{
- if (m_Path.IsNull()) {
- return;
- }
- CFX_FloatRect rect;
- FX_FLOAT width = m_GraphState.GetObject()->m_LineWidth;
- if (m_bStroke && width != 0) {
- rect = m_Path.GetBoundingBox(width, m_GraphState.GetObject()->m_MiterLimit);
- } else {
- rect = m_Path.GetBoundingBox();
- }
- rect.Transform(&m_Matrix);
- if (width == 0 && m_bStroke) {
- rect.left += -0.5f;
- rect.right += 0.5f;
- rect.bottom += -0.5f;
- rect.top += 0.5f;
- }
- m_Left = rect.left;
- m_Right = rect.right;
- m_Top = rect.top;
- m_Bottom = rect.bottom;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "../../../include/fpdfapi/fpdf_pageobj.h" +#include "../../../include/fpdfapi/fpdf_module.h" +#include "pageint.h" +void CPDF_PathObject::CopyData(const CPDF_PageObject* pSrc) +{ + const CPDF_PathObject* pSrcObj = (const CPDF_PathObject*)pSrc; + m_Path = pSrcObj->m_Path; + m_FillType = pSrcObj->m_FillType; + m_bStroke = pSrcObj->m_bStroke; + m_Matrix = pSrcObj->m_Matrix; +} +void CPDF_PathObject::Transform(const CPDF_Matrix& matrix) +{ + m_Matrix.Concat(matrix); + CalcBoundingBox(); +} +void CPDF_PathObject::SetGraphState(CPDF_GraphState GraphState) +{ + m_GraphState = GraphState; + CalcBoundingBox(); +} +void CPDF_PathObject::CalcBoundingBox() +{ + if (m_Path.IsNull()) { + return; + } + CFX_FloatRect rect; + FX_FLOAT width = m_GraphState.GetObject()->m_LineWidth; + if (m_bStroke && width != 0) { + rect = m_Path.GetBoundingBox(width, m_GraphState.GetObject()->m_MiterLimit); + } else { + rect = m_Path.GetBoundingBox(); + } + rect.Transform(&m_Matrix); + if (width == 0 && m_bStroke) { + rect.left += -0.5f; + rect.right += 0.5f; + rect.bottom += -0.5f; + rect.top += 0.5f; + } + m_Left = rect.left; + m_Right = rect.right; + m_Top = rect.top; + m_Bottom = rect.bottom; +} diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp index aee0367acb..6c6c095980 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp @@ -1,278 +1,278 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_page.h"
-#include "pageint.h"
-CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc, CPDF_Object* pPatternObj, const CFX_AffineMatrix* parentMatrix) :
- CPDF_Pattern(parentMatrix)
-{
- m_PatternType = PATTERN_TILING;
- m_pPatternObj = pPatternObj;
- m_pDocument = pDoc;
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- ASSERT(pDict != NULL);
- m_Pattern2Form = pDict->GetMatrix(FX_BSTRC("Matrix"));
- m_bColored = pDict->GetInteger(FX_BSTRC("PaintType")) == 1;
- if (parentMatrix) {
- m_Pattern2Form.Concat(*parentMatrix);
- }
- m_pForm = NULL;
-}
-CPDF_TilingPattern::~CPDF_TilingPattern()
-{
- if (m_pForm) {
- delete m_pForm;
- }
-}
-FX_BOOL CPDF_TilingPattern::Load()
-{
- if (m_pForm != NULL) {
- return TRUE;
- }
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- if (pDict == NULL) {
- return FALSE;
- }
- m_bColored = pDict->GetInteger(FX_BSTRC("PaintType")) == 1;
- m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumber(FX_BSTRC("XStep")));
- m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumber(FX_BSTRC("YStep")));
- if (m_pPatternObj->GetType() != PDFOBJ_STREAM) {
- return FALSE;
- }
- CPDF_Stream* pStream = (CPDF_Stream*)m_pPatternObj;
- m_pForm = FX_NEW CPDF_Form(m_pDocument, NULL, pStream);
- m_pForm->ParseContent(NULL, &m_ParentMatrix, NULL, NULL);
- m_BBox = pDict->GetRect(FX_BSTRC("BBox"));
- return TRUE;
-}
-CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* parentMatrix) : CPDF_Pattern(parentMatrix)
-{
- m_PatternType = PATTERN_SHADING;
- m_pPatternObj = bShading ? NULL : pPatternObj;
- m_pDocument = pDoc;
- m_bShadingObj = bShading;
- if (!bShading) {
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- ASSERT(pDict != NULL);
- m_Pattern2Form = pDict->GetMatrix(FX_BSTRC("Matrix"));
- m_pShadingObj = pDict->GetElementValue(FX_BSTRC("Shading"));
- if (parentMatrix) {
- m_Pattern2Form.Concat(*parentMatrix);
- }
- } else {
- m_pShadingObj = pPatternObj;
- }
- m_ShadingType = 0;
- m_pCS = NULL;
- m_nFuncs = 0;
- for (int i = 0; i < 4; i ++) {
- m_pFunctions[i] = NULL;
- }
-}
-CPDF_ShadingPattern::~CPDF_ShadingPattern()
-{
- Clear();
-}
-void CPDF_ShadingPattern::Clear()
-{
- for (int i = 0; i < m_nFuncs; i ++) {
- if (m_pFunctions[i]) {
- delete m_pFunctions[i];
- }
- m_pFunctions[i] = NULL;
- }
- CPDF_ColorSpace* pCS = m_pCS;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
- m_ShadingType = 0;
- m_pCS = NULL;
- m_nFuncs = 0;
-}
-FX_BOOL CPDF_ShadingPattern::Load()
-{
- if (m_ShadingType != 0) {
- return TRUE;
- }
- CPDF_Dictionary* pShadingDict = m_pShadingObj->GetDict();
- if (pShadingDict == NULL) {
- return FALSE;
- }
- if (m_nFuncs) {
- for (int i = 0; i < m_nFuncs; i ++)
- if (m_pFunctions[i]) {
- delete m_pFunctions[i];
- }
- m_nFuncs = 0;
- }
- CPDF_Object* pFunc = pShadingDict->GetElementValue(FX_BSTRC("Function"));
- if (pFunc) {
- if (pFunc->GetType() == PDFOBJ_ARRAY) {
- m_nFuncs = ((CPDF_Array*)pFunc)->GetCount();
- if (m_nFuncs > 4) {
- m_nFuncs = 4;
- }
- for (int i = 0; i < m_nFuncs; i ++) {
- m_pFunctions[i] = CPDF_Function::Load(((CPDF_Array*)pFunc)->GetElementValue(i));
- }
- } else {
- m_pFunctions[0] = CPDF_Function::Load(pFunc);
- m_nFuncs = 1;
- }
- }
- CPDF_Object* pCSObj = pShadingDict->GetElementValue(FX_BSTRC("ColorSpace"));
- if (pCSObj == NULL) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
- m_pCS = pDocPageData->GetColorSpace(pCSObj, NULL);
- m_ShadingType = pShadingDict->GetInteger(FX_BSTRC("ShadingType"));
- return TRUE;
-}
-FX_BOOL CPDF_ShadingPattern::Reload()
-{
- Clear();
- return Load();
-}
-FX_BOOL CPDF_MeshStream::Load(CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS)
-{
- m_Stream.LoadAllData(pShadingStream);
- m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize());
- m_pFuncs = pFuncs;
- m_nFuncs = nFuncs;
- m_pCS = pCS;
- CPDF_Dictionary* pDict = pShadingStream->GetDict();
- m_nCoordBits = pDict->GetInteger(FX_BSTRC("BitsPerCoordinate"));
- m_nCompBits = pDict->GetInteger(FX_BSTRC("BitsPerComponent"));
- m_nFlagBits = pDict->GetInteger(FX_BSTRC("BitsPerFlag"));
- if (!m_nCoordBits || !m_nCompBits) {
- return FALSE;
- }
- int nComps = pCS->CountComponents();
- if (nComps > 8) {
- return FALSE;
- }
- m_nComps = nFuncs ? 1 : nComps;
- if (((int)m_nComps < 0) || m_nComps > 8) {
- return FALSE;
- }
- m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1;
- m_CompMax = (1 << m_nCompBits) - 1;
- CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode"));
- if (pDecode == NULL || pDecode->GetCount() != 4 + m_nComps * 2) {
- return FALSE;
- }
- m_xmin = pDecode->GetNumber(0);
- m_xmax = pDecode->GetNumber(1);
- m_ymin = pDecode->GetNumber(2);
- m_ymax = pDecode->GetNumber(3);
- for (FX_DWORD i = 0; i < m_nComps; i ++) {
- m_ColorMin[i] = pDecode->GetNumber(i * 2 + 4);
- m_ColorMax[i] = pDecode->GetNumber(i * 2 + 5);
- }
- return TRUE;
-}
-FX_DWORD CPDF_MeshStream::GetFlag()
-{
- return m_BitStream.GetBits(m_nFlagBits) & 0x03;
-}
-void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y)
-{
- if (m_nCoordBits == 32) {
- x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / (double)m_CoordMax);
- y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / (double)m_CoordMax);
- } else {
- x = m_xmin + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax;
- y = m_ymin + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax;
- }
-}
-void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b)
-{
- FX_DWORD i;
- FX_FLOAT color_value[8];
- for (i = 0; i < m_nComps; i ++) {
- color_value[i] = m_ColorMin[i] + m_BitStream.GetBits(m_nCompBits) * (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax;
- }
- if (m_nFuncs) {
- static const int kMaxResults = 8;
- FX_FLOAT result[kMaxResults];
- int nResults;
- FXSYS_memset32(result, 0, sizeof(result));
- for (FX_DWORD i = 0; i < m_nFuncs; i ++) {
- if (m_pFuncs[i] && m_pFuncs[i]->CountOutputs() <= kMaxResults) {
- m_pFuncs[i]->Call(color_value, 1, result, nResults);
- }
- }
- m_pCS->GetRGB(result, r, g, b);
- } else {
- m_pCS->GetRGB(color_value, r, g, b);
- }
-}
-FX_DWORD CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex, CFX_AffineMatrix* pObject2Bitmap)
-{
- FX_DWORD flag = GetFlag();
- GetCoords(vertex.x, vertex.y);
- pObject2Bitmap->Transform(vertex.x, vertex.y);
- GetColor(vertex.r, vertex.g, vertex.b);
- m_BitStream.ByteAlign();
- return flag;
-}
-FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, int count, CFX_AffineMatrix* pObject2Bitmap)
-{
- for (int i = 0; i < count; i ++) {
- if (m_BitStream.IsEOF()) {
- return FALSE;
- }
- GetCoords(vertex[i].x, vertex[i].y);
- pObject2Bitmap->Transform(vertex[i].x, vertex[i].y);
- GetColor(vertex[i].r, vertex[i].g, vertex[i].b);
- m_BitStream.ByteAlign();
- }
- return TRUE;
-}
-CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix,
- CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS)
-{
- if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM || pFuncs == NULL || pCS == NULL) {
- return CFX_FloatRect(0, 0, 0, 0);
- }
- CPDF_MeshStream stream;
- if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) {
- return CFX_FloatRect(0, 0, 0, 0);
- }
- CFX_FloatRect rect;
- FX_BOOL bStarted = FALSE;
- FX_BOOL bGouraud = type == 4 || type == 5;
- int full_point_count = type == 7 ? 16 : (type == 6 ? 12 : 1);
- int full_color_count = (type == 6 || type == 7) ? 4 : 1;
- while (!stream.m_BitStream.IsEOF()) {
- FX_DWORD flag;
- if (type != 5) {
- flag = stream.GetFlag();
- }
- int point_count = full_point_count, color_count = full_color_count;
- if (!bGouraud && flag) {
- point_count -= 4;
- color_count -= 2;
- }
- for (int i = 0; i < point_count; i ++) {
- FX_FLOAT x, y;
- stream.GetCoords(x, y);
- if (bStarted) {
- rect.UpdateRect(x, y);
- } else {
- rect.InitRect(x, y);
- bStarted = TRUE;
- }
- }
- stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * color_count);
- if (bGouraud) {
- stream.m_BitStream.ByteAlign();
- }
- }
- rect.Transform(pMatrix);
- return rect;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_page.h" +#include "pageint.h" +CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc, CPDF_Object* pPatternObj, const CFX_AffineMatrix* parentMatrix) : + CPDF_Pattern(parentMatrix) +{ + m_PatternType = PATTERN_TILING; + m_pPatternObj = pPatternObj; + m_pDocument = pDoc; + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + ASSERT(pDict != NULL); + m_Pattern2Form = pDict->GetMatrix(FX_BSTRC("Matrix")); + m_bColored = pDict->GetInteger(FX_BSTRC("PaintType")) == 1; + if (parentMatrix) { + m_Pattern2Form.Concat(*parentMatrix); + } + m_pForm = NULL; +} +CPDF_TilingPattern::~CPDF_TilingPattern() +{ + if (m_pForm) { + delete m_pForm; + } +} +FX_BOOL CPDF_TilingPattern::Load() +{ + if (m_pForm != NULL) { + return TRUE; + } + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + if (pDict == NULL) { + return FALSE; + } + m_bColored = pDict->GetInteger(FX_BSTRC("PaintType")) == 1; + m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumber(FX_BSTRC("XStep"))); + m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumber(FX_BSTRC("YStep"))); + if (m_pPatternObj->GetType() != PDFOBJ_STREAM) { + return FALSE; + } + CPDF_Stream* pStream = (CPDF_Stream*)m_pPatternObj; + m_pForm = FX_NEW CPDF_Form(m_pDocument, NULL, pStream); + m_pForm->ParseContent(NULL, &m_ParentMatrix, NULL, NULL); + m_BBox = pDict->GetRect(FX_BSTRC("BBox")); + return TRUE; +} +CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* parentMatrix) : CPDF_Pattern(parentMatrix) +{ + m_PatternType = PATTERN_SHADING; + m_pPatternObj = bShading ? NULL : pPatternObj; + m_pDocument = pDoc; + m_bShadingObj = bShading; + if (!bShading) { + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + ASSERT(pDict != NULL); + m_Pattern2Form = pDict->GetMatrix(FX_BSTRC("Matrix")); + m_pShadingObj = pDict->GetElementValue(FX_BSTRC("Shading")); + if (parentMatrix) { + m_Pattern2Form.Concat(*parentMatrix); + } + } else { + m_pShadingObj = pPatternObj; + } + m_ShadingType = 0; + m_pCS = NULL; + m_nFuncs = 0; + for (int i = 0; i < 4; i ++) { + m_pFunctions[i] = NULL; + } +} +CPDF_ShadingPattern::~CPDF_ShadingPattern() +{ + Clear(); +} +void CPDF_ShadingPattern::Clear() +{ + for (int i = 0; i < m_nFuncs; i ++) { + if (m_pFunctions[i]) { + delete m_pFunctions[i]; + } + m_pFunctions[i] = NULL; + } + CPDF_ColorSpace* pCS = m_pCS; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } + m_ShadingType = 0; + m_pCS = NULL; + m_nFuncs = 0; +} +FX_BOOL CPDF_ShadingPattern::Load() +{ + if (m_ShadingType != 0) { + return TRUE; + } + CPDF_Dictionary* pShadingDict = m_pShadingObj->GetDict(); + if (pShadingDict == NULL) { + return FALSE; + } + if (m_nFuncs) { + for (int i = 0; i < m_nFuncs; i ++) + if (m_pFunctions[i]) { + delete m_pFunctions[i]; + } + m_nFuncs = 0; + } + CPDF_Object* pFunc = pShadingDict->GetElementValue(FX_BSTRC("Function")); + if (pFunc) { + if (pFunc->GetType() == PDFOBJ_ARRAY) { + m_nFuncs = ((CPDF_Array*)pFunc)->GetCount(); + if (m_nFuncs > 4) { + m_nFuncs = 4; + } + for (int i = 0; i < m_nFuncs; i ++) { + m_pFunctions[i] = CPDF_Function::Load(((CPDF_Array*)pFunc)->GetElementValue(i)); + } + } else { + m_pFunctions[0] = CPDF_Function::Load(pFunc); + m_nFuncs = 1; + } + } + CPDF_Object* pCSObj = pShadingDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj == NULL) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); + m_pCS = pDocPageData->GetColorSpace(pCSObj, NULL); + m_ShadingType = pShadingDict->GetInteger(FX_BSTRC("ShadingType")); + return TRUE; +} +FX_BOOL CPDF_ShadingPattern::Reload() +{ + Clear(); + return Load(); +} +FX_BOOL CPDF_MeshStream::Load(CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS) +{ + m_Stream.LoadAllData(pShadingStream); + m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); + m_pFuncs = pFuncs; + m_nFuncs = nFuncs; + m_pCS = pCS; + CPDF_Dictionary* pDict = pShadingStream->GetDict(); + m_nCoordBits = pDict->GetInteger(FX_BSTRC("BitsPerCoordinate")); + m_nCompBits = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); + m_nFlagBits = pDict->GetInteger(FX_BSTRC("BitsPerFlag")); + if (!m_nCoordBits || !m_nCompBits) { + return FALSE; + } + int nComps = pCS->CountComponents(); + if (nComps > 8) { + return FALSE; + } + m_nComps = nFuncs ? 1 : nComps; + if (((int)m_nComps < 0) || m_nComps > 8) { + return FALSE; + } + m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; + m_CompMax = (1 << m_nCompBits) - 1; + CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode")); + if (pDecode == NULL || pDecode->GetCount() != 4 + m_nComps * 2) { + return FALSE; + } + m_xmin = pDecode->GetNumber(0); + m_xmax = pDecode->GetNumber(1); + m_ymin = pDecode->GetNumber(2); + m_ymax = pDecode->GetNumber(3); + for (FX_DWORD i = 0; i < m_nComps; i ++) { + m_ColorMin[i] = pDecode->GetNumber(i * 2 + 4); + m_ColorMax[i] = pDecode->GetNumber(i * 2 + 5); + } + return TRUE; +} +FX_DWORD CPDF_MeshStream::GetFlag() +{ + return m_BitStream.GetBits(m_nFlagBits) & 0x03; +} +void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) +{ + if (m_nCoordBits == 32) { + x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / (double)m_CoordMax); + y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / (double)m_CoordMax); + } else { + x = m_xmin + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; + y = m_ymin + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; + } +} +void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) +{ + FX_DWORD i; + FX_FLOAT color_value[8]; + for (i = 0; i < m_nComps; i ++) { + color_value[i] = m_ColorMin[i] + m_BitStream.GetBits(m_nCompBits) * (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax; + } + if (m_nFuncs) { + static const int kMaxResults = 8; + FX_FLOAT result[kMaxResults]; + int nResults; + FXSYS_memset32(result, 0, sizeof(result)); + for (FX_DWORD i = 0; i < m_nFuncs; i ++) { + if (m_pFuncs[i] && m_pFuncs[i]->CountOutputs() <= kMaxResults) { + m_pFuncs[i]->Call(color_value, 1, result, nResults); + } + } + m_pCS->GetRGB(result, r, g, b); + } else { + m_pCS->GetRGB(color_value, r, g, b); + } +} +FX_DWORD CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex, CFX_AffineMatrix* pObject2Bitmap) +{ + FX_DWORD flag = GetFlag(); + GetCoords(vertex.x, vertex.y); + pObject2Bitmap->Transform(vertex.x, vertex.y); + GetColor(vertex.r, vertex.g, vertex.b); + m_BitStream.ByteAlign(); + return flag; +} +FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, int count, CFX_AffineMatrix* pObject2Bitmap) +{ + for (int i = 0; i < count; i ++) { + if (m_BitStream.IsEOF()) { + return FALSE; + } + GetCoords(vertex[i].x, vertex[i].y); + pObject2Bitmap->Transform(vertex[i].x, vertex[i].y); + GetColor(vertex[i].r, vertex[i].g, vertex[i].b); + m_BitStream.ByteAlign(); + } + return TRUE; +} +CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix, + CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS) +{ + if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM || pFuncs == NULL || pCS == NULL) { + return CFX_FloatRect(0, 0, 0, 0); + } + CPDF_MeshStream stream; + if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) { + return CFX_FloatRect(0, 0, 0, 0); + } + CFX_FloatRect rect; + FX_BOOL bStarted = FALSE; + FX_BOOL bGouraud = type == 4 || type == 5; + int full_point_count = type == 7 ? 16 : (type == 6 ? 12 : 1); + int full_color_count = (type == 6 || type == 7) ? 4 : 1; + while (!stream.m_BitStream.IsEOF()) { + FX_DWORD flag; + if (type != 5) { + flag = stream.GetFlag(); + } + int point_count = full_point_count, color_count = full_color_count; + if (!bGouraud && flag) { + point_count -= 4; + color_count -= 2; + } + for (int i = 0; i < point_count; i ++) { + FX_FLOAT x, y; + stream.GetCoords(x, y); + if (bStarted) { + rect.UpdateRect(x, y); + } else { + rect.InitRect(x, y); + bStarted = TRUE; + } + } + stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * color_count); + if (bGouraud) { + stream.m_BitStream.ByteAlign(); + } + } + rect.Transform(pMatrix); + return rect; +} diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h index b1a83ec236..4e097ca49e 100644 --- a/core/src/fpdfapi/fpdf_page/pageint.h +++ b/core/src/fpdfapi/fpdf_page/pageint.h @@ -1,505 +1,505 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../../include/fpdfapi/fpdf_pageobj.h"
-#define PARSE_STEP_LIMIT 100
-#define STREAM_PARSE_BUFSIZE 20480
-class CPDF_QuickFontCache;
-#ifndef _FPDFAPI_MINI_
-class CPDF_StreamParser : public CFX_Object
-{
-public:
-
- CPDF_StreamParser(const FX_BYTE* pData, FX_DWORD dwSize);
- ~CPDF_StreamParser();
-
- CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode);
- typedef enum { EndOfData, Number, Keyword, Name, Others } SyntaxType;
-
- SyntaxType ParseNextElement();
- FX_LPBYTE GetWordBuf()
- {
- return m_WordBuffer;
- }
- FX_DWORD GetWordSize()
- {
- return m_WordSize;
- }
- CPDF_Object* GetObject()
- {
- CPDF_Object* pObj = m_pLastObj;
- m_pLastObj = NULL;
- return pObj;
- }
- FX_DWORD GetPos()
- {
- return m_Pos;
- }
- void SetPos(FX_DWORD pos)
- {
- m_Pos = pos;
- }
-
- CPDF_Object* ReadNextObject(FX_BOOL bAllowNestedArray = FALSE, FX_BOOL bInArray = FALSE);
- void SkipPathObject();
-protected:
- void GetNextWord(FX_BOOL& bIsNumber);
- CFX_ByteString ReadString();
- CFX_ByteString ReadHexString();
- const FX_BYTE* m_pBuf;
- FX_DWORD m_Size;
- FX_DWORD m_Pos;
- FX_BYTE m_WordBuffer[256];
- FX_DWORD m_WordSize;
- CPDF_Object* m_pLastObj;
-};
-#endif
-typedef enum {
- PDFOP_CloseFillStrokePath = 0, PDFOP_FillStrokePath,
- PDFOP_CloseEOFillStrokePath, PDFOP_EOFillStrokePath,
- PDFOP_BeginMarkedContent_Dictionary, PDFOP_BeginImage,
- PDFOP_BeginMarkedContent, PDFOP_BeginText,
- PDFOP_BeginSectionUndefined, PDFOP_CurveTo_123,
- PDFOP_ConcatMatrix, PDFOP_SetColorSpace_Fill,
- PDFOP_SetColorSpace_Stroke, PDFOP_SetDash,
- PDFOP_SetCharWidth, PDFOP_SetCachedDevice,
- PDFOP_ExecuteXObject, PDFOP_MarkPlace_Dictionary,
- PDFOP_EndImage, PDFOP_EndMarkedContent,
- PDFOP_EndText, PDFOP_EndSectionUndefined,
- PDFOP_FillPath, PDFOP_FillPathOld,
- PDFOP_EOFillPath, PDFOP_SetGray_Fill,
- PDFOP_SetGray_Stroke, PDFOP_SetExtendGraphState,
- PDFOP_ClosePath, PDFOP_SetFlat,
- PDFOP_BeginImageData, PDFOP_SetLineJoin,
- PDFOP_SetLineCap, PDFOP_SetCMYKColor_Fill,
- PDFOP_SetCMYKColor_Stroke, PDFOP_LineTo,
- PDFOP_MoveTo, PDFOP_SetMiterLimit,
- PDFOP_MarkPlace, PDFOP_EndPath,
- PDFOP_SaveGraphState, PDFOP_RestoreGraphState,
- PDFOP_Rectangle, PDFOP_SetRGBColor_Fill,
- PDFOP_SetRGBColor_Stroke, PDFOP_SetRenderIntent,
- PDFOP_CloseStrokePath, PDFOP_StrokePath,
- PDFOP_SetColor_Fill, PDFOP_SetColor_Stroke,
- PDFOP_SetColorPS_Fill, PDFOP_SetColorPS_Stroke,
- PDFOP_ShadeFill, PDFOP_SetCharSpace,
- PDFOP_MoveTextPoint, PDFOP_MoveTextPoint_SetLeading,
- PDFOP_SetFont, PDFOP_ShowText,
- PDFOP_ShowText_Positioning, PDFOP_SetTextLeading,
- PDFOP_SetTextMatrix, PDFOP_SetTextRenderMode,
- PDFOP_SetTextRise, PDFOP_SetWordSpace,
- PDFOP_SetHorzScale, PDFOP_MoveToNextLine,
- PDFOP_CurveTo_23, PDFOP_SetLineWidth,
- PDFOP_Clip, PDFOP_EOClip,
- PDFOP_CurveTo_13, PDFOP_NextLineShowText,
- PDFOP_NextLineShowText_Space, PDFOP_Invalid
-} PDFOP;
-#define PARAM_BUF_SIZE 16
-typedef struct {
- int m_Type;
- union {
- struct {
- FX_BOOL m_bInteger;
- union {
- int m_Integer;
- FX_FLOAT m_Float;
- };
- } m_Number;
- CPDF_Object* m_pObject;
- struct {
- int m_Len;
- char m_Buffer[32];
- } m_Name;
- };
-} _ContentParam;
-#if defined(_FPDFAPI_MINI_)
-#define _FPDF_MAX_FORM_LEVEL_ 17
-#else
-#define _FPDF_MAX_FORM_LEVEL_ 30
-#endif
-#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4
-#define _FPDF_MAX_OBJECT_STACK_SIZE_ 512
-class CPDF_StreamContentParser : public CFX_Object
-{
-public:
- CPDF_StreamContentParser();
- ~CPDF_StreamContentParser();
- FX_BOOL Initialize();
- void PrepareParse(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources,
- CFX_AffineMatrix* pmtContentToUser,
- CPDF_PageObjects* pObjList, CPDF_Dictionary* pResources,
- CFX_FloatRect* pBBox, CPDF_ParseOptions* pOptions,
- CPDF_AllStates* pAllStates, int level);
- CPDF_Document* m_pDocument;
- CPDF_Dictionary* m_pPageResources;
- CPDF_Dictionary* m_pParentResources;
- CPDF_PageObjects* m_pObjectList;
- CPDF_Dictionary* m_pResources;
- int m_Level;
- CFX_AffineMatrix m_mtContentToUser;
- CFX_FloatRect m_BBox;
- CPDF_ParseOptions m_Options;
- _ContentParam m_ParamBuf1[PARAM_BUF_SIZE];
- FX_DWORD m_ParamStartPos;
- FX_DWORD m_ParamCount;
- void AddNumberParam(FX_LPCSTR str, int len);
- void AddObjectParam(CPDF_Object* pObj);
- void AddNameParam(FX_LPCSTR name, int size);
- int GetNextParamPos();
- void ClearAllParams();
- CPDF_Object* GetObject(FX_DWORD index);
- CFX_ByteString GetString(FX_DWORD index);
- FX_FLOAT GetNumber(FX_DWORD index);
- FX_FLOAT GetNumber16(FX_DWORD index);
- int GetInteger(FX_DWORD index)
- {
- return (FX_INT32)(GetNumber(index));
- }
- FX_BOOL OnOperator(FX_LPCSTR op);
- void BigCaseCaller(int index);
- FX_BOOL m_bAbort;
-#ifndef _FPDFAPI_MINI_
- CPDF_StreamParser* m_pSyntax;
- FX_DWORD GetParsePos()
- {
- return m_pSyntax->GetPos();
- }
-#else
- int m_WordState;
- void InputData(FX_LPCBYTE src_buf, FX_DWORD src_size);
- void Finish();
- void StartArray();
- void EndArray();
- void StartDict();
- void EndDict();
- void EndName();
- void EndNumber();
- void EndKeyword();
- void EndHexString();
- void EndString();
- void EndImageDict();
- void EndInlineImage();
- FX_LPBYTE m_pWordBuf;
- FX_DWORD m_WordSize;
- CFX_BinaryBuf m_StringBuf;
- int m_StringLevel, m_StringState, m_EscCode;
- void AddContainer(CPDF_Object* pObject);
- FX_BOOL SetToCurObj(CPDF_Object* pObject);
- FX_LPBYTE m_pDictName;
- FX_BOOL m_bDictName;
- CPDF_Object** m_pObjectStack;
- FX_BOOL* m_pObjectState;
- FX_DWORD m_ObjectSize;
- int m_InlineImageState;
- FX_BYTE m_InlineWhiteChar;
- CFX_BinaryBuf m_ImageSrcBuf;
- FX_LPBYTE m_pStreamBuf;
-#endif
- CPDF_AllStates* m_pCurStates;
- CPDF_ContentMark m_CurContentMark;
- CFX_PtrArray m_ClipTextList;
- CPDF_TextObject* m_pLastTextObject;
- FX_FLOAT m_DefFontSize;
- void AddTextObject(CFX_ByteString* pText, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int count);
-
- void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y);
- void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y);
- void OnChangeTextMatrix();
-#ifndef _FPDFAPI_MINI_
- FX_DWORD Parse(FX_LPCBYTE pData, FX_DWORD dwSize, FX_DWORD max_cost);
- void ParsePathObject();
-#endif
- int m_CompatCount;
- FX_PATHPOINT* m_pPathPoints;
- int m_PathPointCount;
- int m_PathAllocSize;
- FX_FLOAT m_PathStartX, m_PathStartY;
- FX_FLOAT m_PathCurrentX, m_PathCurrentY;
- int m_PathClipType;
- void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag);
- void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h);
- void AddPathObject(int FillType, FX_BOOL bStroke);
- CPDF_ImageObject* AddImage(CPDF_Stream* pStream, CPDF_Image* pImage, FX_BOOL bInline);
- void AddDuplicateImage();
- void AddForm(CPDF_Stream*);
- CFX_ByteString m_LastImageName;
- CPDF_Image* m_pLastImage;
- CFX_BinaryBuf m_LastImageDict, m_LastImageData;
- CPDF_Dictionary* m_pLastImageDict;
- CPDF_Dictionary* m_pLastCloneImageDict;
- FX_BOOL m_bReleaseLastDict;
- FX_BOOL m_bSameLastDict;
- void SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph);
- FX_BOOL m_bColored;
- FX_FLOAT m_Type3Data[6];
- FX_BOOL m_bResourceMissing;
- CFX_PtrArray m_StateStack;
- void SaveStates(CPDF_AllStates*);
- void RestoreStates(CPDF_AllStates*);
- CPDF_Font* FindFont(const CFX_ByteString& name);
- CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name);
- CPDF_Pattern* FindPattern(const CFX_ByteString& name, FX_BOOL bShading);
- CPDF_Object* FindResourceObj(FX_BSTR type, const CFX_ByteString& name);
- void Handle_CloseFillStrokePath();
- void Handle_FillStrokePath();
- void Handle_CloseEOFillStrokePath();
- void Handle_EOFillStrokePath();
- void Handle_BeginMarkedContent_Dictionary();
- void Handle_BeginImage();
- void Handle_BeginMarkedContent();
- void Handle_BeginText();
- void Handle_BeginSectionUndefined();
- void Handle_CurveTo_123();
- void Handle_ConcatMatrix();
- void Handle_SetColorSpace_Fill();
- void Handle_SetColorSpace_Stroke();
- void Handle_SetDash();
- void Handle_SetCharWidth();
- void Handle_SetCachedDevice();
- void Handle_ExecuteXObject();
- void Handle_MarkPlace_Dictionary();
- void Handle_EndImage();
- void Handle_EndMarkedContent();
- void Handle_EndText();
- void Handle_EndSectionUndefined();
- void Handle_FillPath();
- void Handle_FillPathOld();
- void Handle_EOFillPath();
- void Handle_SetGray_Fill();
- void Handle_SetGray_Stroke();
- void Handle_SetExtendGraphState();
- void Handle_ClosePath();
- void Handle_SetFlat();
- void Handle_BeginImageData();
- void Handle_SetLineJoin();
- void Handle_SetLineCap();
- void Handle_SetCMYKColor_Fill();
- void Handle_SetCMYKColor_Stroke();
- void Handle_LineTo();
- void Handle_MoveTo();
- void Handle_SetMiterLimit();
- void Handle_MarkPlace();
- void Handle_EndPath();
- void Handle_SaveGraphState();
- void Handle_RestoreGraphState();
- void Handle_Rectangle();
- void Handle_SetRGBColor_Fill();
- void Handle_SetRGBColor_Stroke();
- void Handle_SetRenderIntent();
- void Handle_CloseStrokePath();
- void Handle_StrokePath();
- void Handle_SetColor_Fill();
- void Handle_SetColor_Stroke();
- void Handle_SetColorPS_Fill();
- void Handle_SetColorPS_Stroke();
- void Handle_ShadeFill();
- void Handle_SetCharSpace();
- void Handle_MoveTextPoint();
- void Handle_MoveTextPoint_SetLeading();
- void Handle_SetFont();
- void Handle_ShowText();
- void Handle_ShowText_Positioning();
- void Handle_SetTextLeading();
- void Handle_SetTextMatrix();
- void Handle_SetTextRenderMode();
- void Handle_SetTextRise();
- void Handle_SetWordSpace();
- void Handle_SetHorzScale();
- void Handle_MoveToNextLine();
- void Handle_CurveTo_23();
- void Handle_SetLineWidth();
- void Handle_Clip();
- void Handle_EOClip();
- void Handle_CurveTo_13();
- void Handle_NextLineShowText();
- void Handle_NextLineShowText_Space();
- void Handle_Invalid();
-};
-class CPDF_ContentParser : public CFX_Object
-{
-public:
- CPDF_ContentParser();
- ~CPDF_ContentParser();
- typedef enum { Ready, ToBeContinued, Done } ParseStatus;
- ParseStatus GetStatus()
- {
- return m_Status;
- }
- void Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions);
- void Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
- CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level);
- void Continue(IFX_Pause* pPause);
- int EstimateProgress();
-protected:
- void Clear();
- ParseStatus m_Status;
- CPDF_PageObjects* m_pObjects;
- FX_BOOL m_bForm;
- CPDF_ParseOptions m_Options;
- CPDF_Type3Char* m_pType3Char;
- int m_InternalStage;
- CPDF_StreamAcc* m_pSingleStream;
- CPDF_StreamAcc** m_pStreamArray;
- FX_DWORD m_nStreams;
- FX_LPBYTE m_pData;
- FX_DWORD m_Size;
- class CPDF_StreamContentParser* m_pParser;
- FX_DWORD m_CurrentOffset;
- CPDF_StreamFilter* m_pStreamFilter;
-};
-class CPDF_AllStates : public CPDF_GraphicStates
-{
-public:
- CPDF_AllStates();
- ~CPDF_AllStates();
- void Copy(const CPDF_AllStates& src);
- void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser);
- void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale);
- CFX_AffineMatrix m_TextMatrix, m_CTM, m_ParentMatrix;
- FX_FLOAT m_TextX, m_TextY, m_TextLineX, m_TextLineY;
- FX_FLOAT m_TextLeading, m_TextRise, m_TextHorzScale;
-};
-template <class ObjClass> class CPDF_CountedObject : public CFX_Object
-{
-public:
- ObjClass m_Obj;
- FX_DWORD m_nCount;
-};
-typedef CFX_MapPtrTemplate<CPDF_Dictionary*, CPDF_CountedObject<CPDF_Font*>*> CPDF_FontMap;
-typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_ColorSpace*>*> CPDF_ColorSpaceMap;
-typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_Pattern*>*> CPDF_PatternMap;
-typedef CFX_MapPtrTemplate<FX_DWORD, CPDF_CountedObject<CPDF_Image*>*> CPDF_ImageMap;
-typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_IccProfile*>*> CPDF_IccProfileMap;
-typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_StreamAcc*>*> CPDF_FontFileMap;
-template <class KeyType, class ValueType>
-KeyType PDF_DocPageData_FindValue(const CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, ValueType findValue, CPDF_CountedObject<ValueType>*& findData)
-{
- FX_POSITION pos = map.GetStartPosition();
- while (pos) {
- KeyType findKey;
- map.GetNextAssoc(pos, findKey, findData);
- if (findData->m_Obj == findValue) {
- return findKey;
- }
- }
- findData = NULL;
- return (KeyType)(FX_UINTPTR)NULL;
-}
-template <class KeyType, class ValueType>
-FX_BOOL PDF_DocPageData_Release(CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, KeyType findKey, ValueType findValue, FX_BOOL bForce = FALSE)
-{
- if (!findKey && !findValue) {
- return FALSE;
- }
- CPDF_CountedObject<ValueType>* findData = NULL;
- if (!findKey) {
- findKey = PDF_DocPageData_FindValue<KeyType, ValueType>(map, findValue, findData);
- } else if (!map.Lookup(findKey, findData)) {
- return FALSE;
- }
- if (findData && ((-- findData->m_nCount) == 0 || bForce)) {
- delete findData->m_Obj;
- delete findData;
- map.RemoveKey(findKey);
- return TRUE;
- }
- return FALSE;
-}
-class CPDF_DocPageData : public CFX_Object
-{
-public:
- CPDF_DocPageData(CPDF_Document *pPDFDoc);
- ~CPDF_DocPageData();
- void Clear(FX_BOOL bRelease = FALSE);
- CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly);
- CPDF_Font* GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding);
- void ReleaseFont(CPDF_Dictionary* pFontDict);
- CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources);
- CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj);
- void ReleaseColorSpace(CPDF_Object* pColorSpace);
- CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix);
- void ReleasePattern(CPDF_Object* pPatternObj);
- CPDF_Image* GetImage(CPDF_Object* pImageStream);
- void ReleaseImage(CPDF_Object* pImageStream);
- CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents);
- void ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile);
- CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream);
- void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE);
- CPDF_Document* m_pPDFDoc;
- CPDF_FontMap m_FontMap;
- CPDF_ColorSpaceMap m_ColorSpaceMap;
- CPDF_PatternMap m_PatternMap;
- CPDF_ImageMap m_ImageMap;
- CPDF_IccProfileMap m_IccProfileMap;
- CFX_MapByteStringToPtr m_HashProfileMap;
- CPDF_FontFileMap m_FontFileMap;
-};
-class CPDF_Function : public CFX_Object
-{
-public:
- static CPDF_Function* Load(CPDF_Object* pFuncObj);
- virtual ~CPDF_Function();
- FX_BOOL Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, int& nresults) const;
- int CountInputs()
- {
- return m_nInputs;
- }
- int CountOutputs()
- {
- return m_nOutputs;
- }
-protected:
- CPDF_Function();
- int m_nInputs, m_nOutputs;
- FX_FLOAT* m_pDomains;
- FX_FLOAT* m_pRanges;
- FX_BOOL Init(CPDF_Object* pObj);
- virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0;
- virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0;
-};
-class CPDF_IccProfile : public CFX_Object
-{
-public:
- CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents);
- ~CPDF_IccProfile();
- FX_BOOL m_bsRGB;
- FX_LPVOID m_pTransform;
-};
-class CPDF_DeviceCS : public CPDF_ColorSpace
-{
-public:
- CPDF_DeviceCS(int family);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
- FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const;
- FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const;
- virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
-};
-class CPDF_PatternCS : public CPDF_ColorSpace
-{
-public:
- CPDF_PatternCS();
- ~CPDF_PatternCS();
- virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
- virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
- virtual CPDF_ColorSpace* GetBaseCS() const
- {
- return m_pBaseCS;
- }
- CPDF_ColorSpace* m_pBaseCS;
-};
-#define MAX_PAGE_OBJECTS_UNIFY_NAMING 4096
-class CPDF_ResourceNaming : public CFX_Object
-{
-public:
- struct _NamingState : public CFX_Object {
- CFX_ByteString m_Prefix;
- int m_nIndex;
- };
- ~CPDF_ResourceNaming();
- CFX_ByteString GetName(const CPDF_Dictionary* pResList, FX_LPCSTR szType);
-protected:
- CFX_MapByteStringToPtr m_NamingCache;
-};
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../../include/fpdfapi/fpdf_pageobj.h" +#define PARSE_STEP_LIMIT 100 +#define STREAM_PARSE_BUFSIZE 20480 +class CPDF_QuickFontCache; +#ifndef _FPDFAPI_MINI_ +class CPDF_StreamParser : public CFX_Object +{ +public: + + CPDF_StreamParser(const FX_BYTE* pData, FX_DWORD dwSize); + ~CPDF_StreamParser(); + + CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode); + typedef enum { EndOfData, Number, Keyword, Name, Others } SyntaxType; + + SyntaxType ParseNextElement(); + FX_LPBYTE GetWordBuf() + { + return m_WordBuffer; + } + FX_DWORD GetWordSize() + { + return m_WordSize; + } + CPDF_Object* GetObject() + { + CPDF_Object* pObj = m_pLastObj; + m_pLastObj = NULL; + return pObj; + } + FX_DWORD GetPos() + { + return m_Pos; + } + void SetPos(FX_DWORD pos) + { + m_Pos = pos; + } + + CPDF_Object* ReadNextObject(FX_BOOL bAllowNestedArray = FALSE, FX_BOOL bInArray = FALSE); + void SkipPathObject(); +protected: + void GetNextWord(FX_BOOL& bIsNumber); + CFX_ByteString ReadString(); + CFX_ByteString ReadHexString(); + const FX_BYTE* m_pBuf; + FX_DWORD m_Size; + FX_DWORD m_Pos; + FX_BYTE m_WordBuffer[256]; + FX_DWORD m_WordSize; + CPDF_Object* m_pLastObj; +}; +#endif +typedef enum { + PDFOP_CloseFillStrokePath = 0, PDFOP_FillStrokePath, + PDFOP_CloseEOFillStrokePath, PDFOP_EOFillStrokePath, + PDFOP_BeginMarkedContent_Dictionary, PDFOP_BeginImage, + PDFOP_BeginMarkedContent, PDFOP_BeginText, + PDFOP_BeginSectionUndefined, PDFOP_CurveTo_123, + PDFOP_ConcatMatrix, PDFOP_SetColorSpace_Fill, + PDFOP_SetColorSpace_Stroke, PDFOP_SetDash, + PDFOP_SetCharWidth, PDFOP_SetCachedDevice, + PDFOP_ExecuteXObject, PDFOP_MarkPlace_Dictionary, + PDFOP_EndImage, PDFOP_EndMarkedContent, + PDFOP_EndText, PDFOP_EndSectionUndefined, + PDFOP_FillPath, PDFOP_FillPathOld, + PDFOP_EOFillPath, PDFOP_SetGray_Fill, + PDFOP_SetGray_Stroke, PDFOP_SetExtendGraphState, + PDFOP_ClosePath, PDFOP_SetFlat, + PDFOP_BeginImageData, PDFOP_SetLineJoin, + PDFOP_SetLineCap, PDFOP_SetCMYKColor_Fill, + PDFOP_SetCMYKColor_Stroke, PDFOP_LineTo, + PDFOP_MoveTo, PDFOP_SetMiterLimit, + PDFOP_MarkPlace, PDFOP_EndPath, + PDFOP_SaveGraphState, PDFOP_RestoreGraphState, + PDFOP_Rectangle, PDFOP_SetRGBColor_Fill, + PDFOP_SetRGBColor_Stroke, PDFOP_SetRenderIntent, + PDFOP_CloseStrokePath, PDFOP_StrokePath, + PDFOP_SetColor_Fill, PDFOP_SetColor_Stroke, + PDFOP_SetColorPS_Fill, PDFOP_SetColorPS_Stroke, + PDFOP_ShadeFill, PDFOP_SetCharSpace, + PDFOP_MoveTextPoint, PDFOP_MoveTextPoint_SetLeading, + PDFOP_SetFont, PDFOP_ShowText, + PDFOP_ShowText_Positioning, PDFOP_SetTextLeading, + PDFOP_SetTextMatrix, PDFOP_SetTextRenderMode, + PDFOP_SetTextRise, PDFOP_SetWordSpace, + PDFOP_SetHorzScale, PDFOP_MoveToNextLine, + PDFOP_CurveTo_23, PDFOP_SetLineWidth, + PDFOP_Clip, PDFOP_EOClip, + PDFOP_CurveTo_13, PDFOP_NextLineShowText, + PDFOP_NextLineShowText_Space, PDFOP_Invalid +} PDFOP; +#define PARAM_BUF_SIZE 16 +typedef struct { + int m_Type; + union { + struct { + FX_BOOL m_bInteger; + union { + int m_Integer; + FX_FLOAT m_Float; + }; + } m_Number; + CPDF_Object* m_pObject; + struct { + int m_Len; + char m_Buffer[32]; + } m_Name; + }; +} _ContentParam; +#if defined(_FPDFAPI_MINI_) +#define _FPDF_MAX_FORM_LEVEL_ 17 +#else +#define _FPDF_MAX_FORM_LEVEL_ 30 +#endif +#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4 +#define _FPDF_MAX_OBJECT_STACK_SIZE_ 512 +class CPDF_StreamContentParser : public CFX_Object +{ +public: + CPDF_StreamContentParser(); + ~CPDF_StreamContentParser(); + FX_BOOL Initialize(); + void PrepareParse(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources, + CFX_AffineMatrix* pmtContentToUser, + CPDF_PageObjects* pObjList, CPDF_Dictionary* pResources, + CFX_FloatRect* pBBox, CPDF_ParseOptions* pOptions, + CPDF_AllStates* pAllStates, int level); + CPDF_Document* m_pDocument; + CPDF_Dictionary* m_pPageResources; + CPDF_Dictionary* m_pParentResources; + CPDF_PageObjects* m_pObjectList; + CPDF_Dictionary* m_pResources; + int m_Level; + CFX_AffineMatrix m_mtContentToUser; + CFX_FloatRect m_BBox; + CPDF_ParseOptions m_Options; + _ContentParam m_ParamBuf1[PARAM_BUF_SIZE]; + FX_DWORD m_ParamStartPos; + FX_DWORD m_ParamCount; + void AddNumberParam(FX_LPCSTR str, int len); + void AddObjectParam(CPDF_Object* pObj); + void AddNameParam(FX_LPCSTR name, int size); + int GetNextParamPos(); + void ClearAllParams(); + CPDF_Object* GetObject(FX_DWORD index); + CFX_ByteString GetString(FX_DWORD index); + FX_FLOAT GetNumber(FX_DWORD index); + FX_FLOAT GetNumber16(FX_DWORD index); + int GetInteger(FX_DWORD index) + { + return (FX_INT32)(GetNumber(index)); + } + FX_BOOL OnOperator(FX_LPCSTR op); + void BigCaseCaller(int index); + FX_BOOL m_bAbort; +#ifndef _FPDFAPI_MINI_ + CPDF_StreamParser* m_pSyntax; + FX_DWORD GetParsePos() + { + return m_pSyntax->GetPos(); + } +#else + int m_WordState; + void InputData(FX_LPCBYTE src_buf, FX_DWORD src_size); + void Finish(); + void StartArray(); + void EndArray(); + void StartDict(); + void EndDict(); + void EndName(); + void EndNumber(); + void EndKeyword(); + void EndHexString(); + void EndString(); + void EndImageDict(); + void EndInlineImage(); + FX_LPBYTE m_pWordBuf; + FX_DWORD m_WordSize; + CFX_BinaryBuf m_StringBuf; + int m_StringLevel, m_StringState, m_EscCode; + void AddContainer(CPDF_Object* pObject); + FX_BOOL SetToCurObj(CPDF_Object* pObject); + FX_LPBYTE m_pDictName; + FX_BOOL m_bDictName; + CPDF_Object** m_pObjectStack; + FX_BOOL* m_pObjectState; + FX_DWORD m_ObjectSize; + int m_InlineImageState; + FX_BYTE m_InlineWhiteChar; + CFX_BinaryBuf m_ImageSrcBuf; + FX_LPBYTE m_pStreamBuf; +#endif + CPDF_AllStates* m_pCurStates; + CPDF_ContentMark m_CurContentMark; + CFX_PtrArray m_ClipTextList; + CPDF_TextObject* m_pLastTextObject; + FX_FLOAT m_DefFontSize; + void AddTextObject(CFX_ByteString* pText, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int count); + + void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y); + void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y); + void OnChangeTextMatrix(); +#ifndef _FPDFAPI_MINI_ + FX_DWORD Parse(FX_LPCBYTE pData, FX_DWORD dwSize, FX_DWORD max_cost); + void ParsePathObject(); +#endif + int m_CompatCount; + FX_PATHPOINT* m_pPathPoints; + int m_PathPointCount; + int m_PathAllocSize; + FX_FLOAT m_PathStartX, m_PathStartY; + FX_FLOAT m_PathCurrentX, m_PathCurrentY; + int m_PathClipType; + void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); + void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); + void AddPathObject(int FillType, FX_BOOL bStroke); + CPDF_ImageObject* AddImage(CPDF_Stream* pStream, CPDF_Image* pImage, FX_BOOL bInline); + void AddDuplicateImage(); + void AddForm(CPDF_Stream*); + CFX_ByteString m_LastImageName; + CPDF_Image* m_pLastImage; + CFX_BinaryBuf m_LastImageDict, m_LastImageData; + CPDF_Dictionary* m_pLastImageDict; + CPDF_Dictionary* m_pLastCloneImageDict; + FX_BOOL m_bReleaseLastDict; + FX_BOOL m_bSameLastDict; + void SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph); + FX_BOOL m_bColored; + FX_FLOAT m_Type3Data[6]; + FX_BOOL m_bResourceMissing; + CFX_PtrArray m_StateStack; + void SaveStates(CPDF_AllStates*); + void RestoreStates(CPDF_AllStates*); + CPDF_Font* FindFont(const CFX_ByteString& name); + CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name); + CPDF_Pattern* FindPattern(const CFX_ByteString& name, FX_BOOL bShading); + CPDF_Object* FindResourceObj(FX_BSTR type, const CFX_ByteString& name); + void Handle_CloseFillStrokePath(); + void Handle_FillStrokePath(); + void Handle_CloseEOFillStrokePath(); + void Handle_EOFillStrokePath(); + void Handle_BeginMarkedContent_Dictionary(); + void Handle_BeginImage(); + void Handle_BeginMarkedContent(); + void Handle_BeginText(); + void Handle_BeginSectionUndefined(); + void Handle_CurveTo_123(); + void Handle_ConcatMatrix(); + void Handle_SetColorSpace_Fill(); + void Handle_SetColorSpace_Stroke(); + void Handle_SetDash(); + void Handle_SetCharWidth(); + void Handle_SetCachedDevice(); + void Handle_ExecuteXObject(); + void Handle_MarkPlace_Dictionary(); + void Handle_EndImage(); + void Handle_EndMarkedContent(); + void Handle_EndText(); + void Handle_EndSectionUndefined(); + void Handle_FillPath(); + void Handle_FillPathOld(); + void Handle_EOFillPath(); + void Handle_SetGray_Fill(); + void Handle_SetGray_Stroke(); + void Handle_SetExtendGraphState(); + void Handle_ClosePath(); + void Handle_SetFlat(); + void Handle_BeginImageData(); + void Handle_SetLineJoin(); + void Handle_SetLineCap(); + void Handle_SetCMYKColor_Fill(); + void Handle_SetCMYKColor_Stroke(); + void Handle_LineTo(); + void Handle_MoveTo(); + void Handle_SetMiterLimit(); + void Handle_MarkPlace(); + void Handle_EndPath(); + void Handle_SaveGraphState(); + void Handle_RestoreGraphState(); + void Handle_Rectangle(); + void Handle_SetRGBColor_Fill(); + void Handle_SetRGBColor_Stroke(); + void Handle_SetRenderIntent(); + void Handle_CloseStrokePath(); + void Handle_StrokePath(); + void Handle_SetColor_Fill(); + void Handle_SetColor_Stroke(); + void Handle_SetColorPS_Fill(); + void Handle_SetColorPS_Stroke(); + void Handle_ShadeFill(); + void Handle_SetCharSpace(); + void Handle_MoveTextPoint(); + void Handle_MoveTextPoint_SetLeading(); + void Handle_SetFont(); + void Handle_ShowText(); + void Handle_ShowText_Positioning(); + void Handle_SetTextLeading(); + void Handle_SetTextMatrix(); + void Handle_SetTextRenderMode(); + void Handle_SetTextRise(); + void Handle_SetWordSpace(); + void Handle_SetHorzScale(); + void Handle_MoveToNextLine(); + void Handle_CurveTo_23(); + void Handle_SetLineWidth(); + void Handle_Clip(); + void Handle_EOClip(); + void Handle_CurveTo_13(); + void Handle_NextLineShowText(); + void Handle_NextLineShowText_Space(); + void Handle_Invalid(); +}; +class CPDF_ContentParser : public CFX_Object +{ +public: + CPDF_ContentParser(); + ~CPDF_ContentParser(); + typedef enum { Ready, ToBeContinued, Done } ParseStatus; + ParseStatus GetStatus() + { + return m_Status; + } + void Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions); + void Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix, + CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level); + void Continue(IFX_Pause* pPause); + int EstimateProgress(); +protected: + void Clear(); + ParseStatus m_Status; + CPDF_PageObjects* m_pObjects; + FX_BOOL m_bForm; + CPDF_ParseOptions m_Options; + CPDF_Type3Char* m_pType3Char; + int m_InternalStage; + CPDF_StreamAcc* m_pSingleStream; + CPDF_StreamAcc** m_pStreamArray; + FX_DWORD m_nStreams; + FX_LPBYTE m_pData; + FX_DWORD m_Size; + class CPDF_StreamContentParser* m_pParser; + FX_DWORD m_CurrentOffset; + CPDF_StreamFilter* m_pStreamFilter; +}; +class CPDF_AllStates : public CPDF_GraphicStates +{ +public: + CPDF_AllStates(); + ~CPDF_AllStates(); + void Copy(const CPDF_AllStates& src); + void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser); + void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale); + CFX_AffineMatrix m_TextMatrix, m_CTM, m_ParentMatrix; + FX_FLOAT m_TextX, m_TextY, m_TextLineX, m_TextLineY; + FX_FLOAT m_TextLeading, m_TextRise, m_TextHorzScale; +}; +template <class ObjClass> class CPDF_CountedObject : public CFX_Object +{ +public: + ObjClass m_Obj; + FX_DWORD m_nCount; +}; +typedef CFX_MapPtrTemplate<CPDF_Dictionary*, CPDF_CountedObject<CPDF_Font*>*> CPDF_FontMap; +typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_ColorSpace*>*> CPDF_ColorSpaceMap; +typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_Pattern*>*> CPDF_PatternMap; +typedef CFX_MapPtrTemplate<FX_DWORD, CPDF_CountedObject<CPDF_Image*>*> CPDF_ImageMap; +typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_IccProfile*>*> CPDF_IccProfileMap; +typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_StreamAcc*>*> CPDF_FontFileMap; +template <class KeyType, class ValueType> +KeyType PDF_DocPageData_FindValue(const CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, ValueType findValue, CPDF_CountedObject<ValueType>*& findData) +{ + FX_POSITION pos = map.GetStartPosition(); + while (pos) { + KeyType findKey; + map.GetNextAssoc(pos, findKey, findData); + if (findData->m_Obj == findValue) { + return findKey; + } + } + findData = NULL; + return (KeyType)(FX_UINTPTR)NULL; +} +template <class KeyType, class ValueType> +FX_BOOL PDF_DocPageData_Release(CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, KeyType findKey, ValueType findValue, FX_BOOL bForce = FALSE) +{ + if (!findKey && !findValue) { + return FALSE; + } + CPDF_CountedObject<ValueType>* findData = NULL; + if (!findKey) { + findKey = PDF_DocPageData_FindValue<KeyType, ValueType>(map, findValue, findData); + } else if (!map.Lookup(findKey, findData)) { + return FALSE; + } + if (findData && ((-- findData->m_nCount) == 0 || bForce)) { + delete findData->m_Obj; + delete findData; + map.RemoveKey(findKey); + return TRUE; + } + return FALSE; +} +class CPDF_DocPageData : public CFX_Object +{ +public: + CPDF_DocPageData(CPDF_Document *pPDFDoc); + ~CPDF_DocPageData(); + void Clear(FX_BOOL bRelease = FALSE); + CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly); + CPDF_Font* GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding); + void ReleaseFont(CPDF_Dictionary* pFontDict); + CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources); + CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj); + void ReleaseColorSpace(CPDF_Object* pColorSpace); + CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix); + void ReleasePattern(CPDF_Object* pPatternObj); + CPDF_Image* GetImage(CPDF_Object* pImageStream); + void ReleaseImage(CPDF_Object* pImageStream); + CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents); + void ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile); + CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream); + void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE); + CPDF_Document* m_pPDFDoc; + CPDF_FontMap m_FontMap; + CPDF_ColorSpaceMap m_ColorSpaceMap; + CPDF_PatternMap m_PatternMap; + CPDF_ImageMap m_ImageMap; + CPDF_IccProfileMap m_IccProfileMap; + CFX_MapByteStringToPtr m_HashProfileMap; + CPDF_FontFileMap m_FontFileMap; +}; +class CPDF_Function : public CFX_Object +{ +public: + static CPDF_Function* Load(CPDF_Object* pFuncObj); + virtual ~CPDF_Function(); + FX_BOOL Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, int& nresults) const; + int CountInputs() + { + return m_nInputs; + } + int CountOutputs() + { + return m_nOutputs; + } +protected: + CPDF_Function(); + int m_nInputs, m_nOutputs; + FX_FLOAT* m_pDomains; + FX_FLOAT* m_pRanges; + FX_BOOL Init(CPDF_Object* pObj); + virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0; + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0; +}; +class CPDF_IccProfile : public CFX_Object +{ +public: + CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize, int nComponents); + ~CPDF_IccProfile(); + FX_BOOL m_bsRGB; + FX_LPVOID m_pTransform; +}; +class CPDF_DeviceCS : public CPDF_ColorSpace +{ +public: + CPDF_DeviceCS(int family); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const; + FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const; + FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const; + virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const; +}; +class CPDF_PatternCS : public CPDF_ColorSpace +{ +public: + CPDF_PatternCS(); + ~CPDF_PatternCS(); + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const; + virtual CPDF_ColorSpace* GetBaseCS() const + { + return m_pBaseCS; + } + CPDF_ColorSpace* m_pBaseCS; +}; +#define MAX_PAGE_OBJECTS_UNIFY_NAMING 4096 +class CPDF_ResourceNaming : public CFX_Object +{ +public: + struct _NamingState : public CFX_Object { + CFX_ByteString m_Prefix; + int m_nIndex; + }; + ~CPDF_ResourceNaming(); + CFX_ByteString GetName(const CPDF_Dictionary* pResList, FX_LPCSTR szType); +protected: + CFX_MapByteStringToPtr m_NamingCache; +}; |