From 3f3b45cc74b0499912409f766a595945dbbfc4c5 Mon Sep 17 00:00:00 2001 From: John Abd-El-Malek Date: Fri, 23 May 2014 17:28:10 -0700 Subject: Convert all line endings to LF. --- core/src/fpdfapi/fpdf_page/fpdf_page.cpp | 2094 +++++++++++++++--------------- 1 file changed, 1047 insertions(+), 1047 deletions(-) (limited to 'core/src/fpdfapi/fpdf_page/fpdf_page.cpp') 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; +} -- cgit v1.2.3