1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fpdfapi/fpdf_page.h"
8 #include "../../../include/fpdfapi/fpdf_module.h"
10 CPDF_PageObject* CPDF_PageObject::Create(int type)
14 return new CPDF_TextObject;
16 return new CPDF_ImageObject;
18 return new CPDF_PathObject;
20 return new CPDF_ShadingObject;
22 return new CPDF_FormObject;
26 CPDF_PageObject::~CPDF_PageObject()
29 CPDF_PageObject* CPDF_PageObject::Clone() const
31 CPDF_PageObject* pObj = Create(m_Type);
35 void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc)
37 if (m_Type != pSrc->m_Type) {
42 m_Left = pSrc->m_Left;
43 m_Right = pSrc->m_Right;
45 m_Bottom = pSrc->m_Bottom;
47 void CPDF_PageObject::AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge)
49 m_ClipPath.AppendPath(path, type, bAutoMerge);
51 void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj)
53 m_ClipPath = pObj->m_ClipPath;
55 void CPDF_PageObject::RemoveClipPath()
59 void CPDF_PageObject::RecalcBBox()
63 ((CPDF_TextObject*)this)->RecalcPositionData();
66 ((CPDF_PathObject*)this)->CalcBoundingBox();
69 ((CPDF_ShadingObject*)this)->CalcBoundingBox();
73 void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix)
75 if (m_ClipPath.IsNull()) {
78 m_ClipPath.GetModify();
79 m_ClipPath.Transform(matrix);
81 void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix)
83 if(m_GeneralState.IsNull()) {
86 CPDF_GeneralStateData* pGS = m_GeneralState.GetModify();
87 pGS->m_Matrix.Concat(matrix);
89 FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const
91 CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top);
93 pMatrix->TransformRect(rect);
95 return rect.GetOutterRect();
97 CPDF_TextObject::CPDF_TextObject()
99 m_Type = PDFPAGE_TEXT;
105 CPDF_TextObject::~CPDF_TextObject()
107 if (m_nChars > 1 && m_pCharCodes) {
108 FX_Free(m_pCharCodes);
114 void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const
116 pInfo->m_CharCode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[index];
117 pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0;
118 pInfo->m_OriginY = 0;
119 if (pInfo->m_CharCode == -1) {
122 CPDF_Font* pFont = m_TextState.GetFont();
123 if (pFont->GetFontType() != PDFFONT_CIDFONT) {
126 if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) {
129 FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode);
130 pInfo->m_OriginY = pInfo->m_OriginX;
131 pInfo->m_OriginX = 0;
133 ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy);
134 FX_FLOAT fontsize = m_TextState.GetFontSize();
135 pInfo->m_OriginX -= fontsize * vx / 1000;
136 pInfo->m_OriginY -= fontsize * vy / 1000;
138 int CPDF_TextObject::CountChars() const
144 for (int i = 0; i < m_nChars; i ++)
145 if (m_pCharCodes[i] != (FX_DWORD) - 1) {
150 void CPDF_TextObject::GetCharInfo(int index, FX_DWORD& charcode, FX_FLOAT& kerning) const
153 charcode = (FX_DWORD)(FX_UINTPTR)m_pCharCodes;
158 for (int i = 0; i < m_nChars; i ++) {
159 if (m_pCharCodes[i] != (FX_DWORD) - 1) {
160 if (count == index) {
161 charcode = m_pCharCodes[i];
162 if (i == m_nChars - 1 || m_pCharCodes[i + 1] != (FX_DWORD) - 1) {
165 kerning = m_pCharPos[i];
173 void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const
176 GetItemInfo(0, pInfo);
180 for (int i = 0; i < m_nChars; i ++) {
181 FX_DWORD charcode = m_pCharCodes[i];
182 if (charcode == (FX_DWORD) - 1) {
185 if (count == index) {
186 GetItemInfo(i, pInfo);
192 void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc)
194 const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc;
195 if (m_nChars > 1 && m_pCharCodes) {
196 FX_Free(m_pCharCodes);
203 m_nChars = pSrcObj->m_nChars;
205 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
206 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
208 for (i = 0; i < m_nChars; i ++) {
209 m_pCharCodes[i] = pSrcObj->m_pCharCodes[i];
211 for (i = 0; i < m_nChars - 1; i ++) {
212 m_pCharPos[i] = pSrcObj->m_pCharPos[i];
215 m_pCharCodes = pSrcObj->m_pCharCodes;
217 m_PosX = pSrcObj->m_PosX;
218 m_PosY = pSrcObj->m_PosY;
220 void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const
222 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
223 pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], m_PosX, m_PosY);
225 void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nsegs)
227 if (m_nChars > 1 && m_pCharCodes) {
228 FX_Free(m_pCharCodes);
235 CPDF_Font* pFont = m_TextState.GetFont();
237 for (int i = 0; i < nsegs; i ++) {
238 m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength());
240 m_nChars += nsegs - 1;
242 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
243 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
245 for (int i = 0; i < nsegs; i ++) {
246 FX_LPCSTR segment = pStrs[i];
247 int offset = 0, len = pStrs[i].GetLength();
248 while (offset < len) {
249 m_pCharCodes[index++] = pFont->GetNextChar(segment, len, offset);
251 if (i != nsegs - 1) {
252 m_pCharPos[index - 1] = pKerning[i];
253 m_pCharCodes[index ++] = (FX_DWORD) - 1;
258 m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pFont->GetNextChar(pStrs[0], pStrs[0].GetLength(), offset);
261 void CPDF_TextObject::SetText(const CFX_ByteString& str)
263 SetSegments(&str, NULL, 1);
264 RecalcPositionData();
266 void CPDF_TextObject::SetEmpty()
268 if (m_nChars > 1 && m_pCharCodes) {
269 FX_Free(m_pCharCodes);
271 if (m_nChars > 1 && m_pCharPos) {
277 m_Left = m_Right = m_PosX;
278 m_Top = m_Bottom = m_PosY;
280 void CPDF_TextObject::SetText(CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs)
282 SetSegments(pStrs, pKerning, nSegs);
283 RecalcPositionData();
285 void CPDF_TextObject::SetText(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pKernings)
287 if (m_nChars > 1 && m_pCharCodes) {
288 FX_Free(m_pCharCodes);
297 for (i = 0; i < nChars - 1; i ++)
298 if (pKernings[i] != 0) {
301 m_nChars = nChars + nKernings;
303 m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
304 m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
306 for (int i = 0; i < nChars; i ++) {
307 m_pCharCodes[index++] = pCharCodes[i];
308 if (pKernings[i] != 0 && i != nChars - 1) {
309 m_pCharCodes[index] = (FX_DWORD) - 1;
310 m_pCharPos[index - 1] = pKernings[i];
315 m_pCharCodes = (FX_DWORD*)(FX_UINTPTR)pCharCodes[0];
317 RecalcPositionData();
319 FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const
321 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
322 CPDF_Font* pFont = m_TextState.GetFont();
323 FX_BOOL bVertWriting = FALSE;
324 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
326 bVertWriting = pCIDFont->IsVertWriting();
329 return pFont->GetCharWidthF(charcode, 0) * fontsize;
331 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
332 return pCIDFont->GetVertWidth(CID) * fontsize;
335 FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const
337 CPDF_Font* pFont = m_TextState.GetFont();
338 FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32);
339 if (charCode != (FX_DWORD) - 1) {
340 return GetCharWidth(charCode);
342 FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f;
343 FX_BOOL bVertWriting = FALSE;
344 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
346 bVertWriting = pCIDFont->IsVertWriting();
349 pFont->GetFontBBox(fontRect);
350 fontSize *= bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width();
353 void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const
355 CPDF_Font* pFont = m_TextState.GetFont();
356 FX_BOOL bVertWriting = FALSE;
357 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
359 bVertWriting = pCIDFont->IsVertWriting();
361 FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
363 for (int i = 0; i < m_nChars; i ++) {
364 FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
365 if (charcode == (FX_DWORD) - 1) {
368 if( count != index) {
372 FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0;
374 pFont->GetCharBBox(charcode, char_rect, 0);
376 rect.left = curpos + char_rect.left * fontsize;
377 rect.right = curpos + char_rect.right * fontsize;
378 rect.top = char_rect.top * fontsize;
379 rect.bottom = char_rect.bottom * fontsize;
381 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
383 pCIDFont->GetVertOrigin(CID, vx, vy);
384 char_rect.left -= vx;
385 char_rect.right -= vx;
387 char_rect.bottom -= vy;
388 rect.left = char_rect.left * fontsize;
389 rect.right = char_rect.right * fontsize;
390 rect.top = curpos + char_rect.top * fontsize;
391 rect.bottom = curpos + char_rect.bottom * fontsize;
396 void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, FX_FLOAT horz_scale, int level)
399 FX_FLOAT min_x = 10000 * 1.0f, max_x = -10000 * 1.0f, min_y = 10000 * 1.0f, max_y = -10000 * 1.0f;
400 CPDF_Font* pFont = m_TextState.GetFont();
401 FX_BOOL bVertWriting = FALSE;
402 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
404 bVertWriting = pCIDFont->IsVertWriting();
406 FX_FLOAT fontsize = m_TextState.GetFontSize();
407 for (int i = 0; i < m_nChars; i ++) {
408 FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
409 if (charcode == (FX_DWORD) - 1) {
410 curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
414 m_pCharPos[i - 1] = curpos;
417 pFont->GetCharBBox(charcode, char_rect, level);
420 if (min_y > char_rect.top) {
421 min_y = (FX_FLOAT)char_rect.top;
423 if (max_y < char_rect.top) {
424 max_y = (FX_FLOAT)char_rect.top;
426 if (min_y > char_rect.bottom) {
427 min_y = (FX_FLOAT)char_rect.bottom;
429 if (max_y < char_rect.bottom) {
430 max_y = (FX_FLOAT)char_rect.bottom;
432 FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
433 FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
434 if (min_x > char_left) {
437 if (max_x < char_left) {
440 if (min_x > char_right) {
443 if (max_x < char_right) {
446 charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
448 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
450 pCIDFont->GetVertOrigin(CID, vx, vy);
451 char_rect.left -= vx;
452 char_rect.right -= vx;
454 char_rect.bottom -= vy;
455 if (min_x > char_rect.left) {
456 min_x = (FX_FLOAT)char_rect.left;
458 if (max_x < char_rect.left) {
459 max_x = (FX_FLOAT)char_rect.left;
461 if (min_x > char_rect.right) {
462 min_x = (FX_FLOAT)char_rect.right;
464 if (max_x < char_rect.right) {
465 max_x = (FX_FLOAT)char_rect.right;
467 FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
468 FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
469 if (min_y > char_top) {
472 if (max_y < char_top) {
475 if (min_y > char_bottom) {
478 if (max_y < char_bottom) {
481 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
484 if (charcode == ' ' && (pCIDFont == NULL || pCIDFont->GetCharSize(32) == 1)) {
485 curpos += m_TextState.GetObject()->m_WordSpace;
487 curpos += m_TextState.GetObject()->m_CharSpace;
494 *pTextAdvanceY = curpos;
496 min_x = min_x * fontsize / 1000;
497 max_x = max_x * fontsize / 1000;
500 *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
505 min_y = min_y * fontsize / 1000;
506 max_y = max_y * fontsize / 1000;
508 CFX_AffineMatrix matrix;
509 GetTextMatrix(&matrix);
514 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
515 int textmode = m_TextState.GetObject()->m_TextMode;
516 if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
517 FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
518 m_Left -= half_width;
519 m_Right += half_width;
521 m_Bottom -= half_width;
524 void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const
526 CPDF_Font* pFont = m_TextState.GetFont();
527 FX_BOOL bVertWriting = FALSE;
528 CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
530 bVertWriting = pCIDFont->IsVertWriting();
532 FX_FLOAT fontsize = m_TextState.GetFontSize();
534 for (int i = 0; i < m_nChars; i ++) {
535 FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)m_pCharCodes : m_pCharCodes[i];
536 if (charcode == (FX_DWORD) - 1) {
539 pPosArray[index++] = i ? m_pCharPos[i - 1] : 0;
542 FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
543 charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
545 charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000;
547 pPosArray[index] = pPosArray[index - 1] + charwidth;
551 void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix)
553 m_TextState.GetModify();
554 CFX_AffineMatrix text_matrix;
555 GetTextMatrix(&text_matrix);
556 text_matrix.Concat(matrix);
557 FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
558 pTextMatrix[0] = text_matrix.GetA();
559 pTextMatrix[1] = text_matrix.GetC();
560 pTextMatrix[2] = text_matrix.GetB();
561 pTextMatrix[3] = text_matrix.GetD();
562 m_PosX = text_matrix.GetE();
563 m_PosY = text_matrix.GetF();
564 CalcPositionData(NULL, NULL, 0);
566 void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y)
568 FX_FLOAT dx = x - m_PosX;
569 FX_FLOAT dy = y - m_PosY;
577 void CPDF_TextObject::SetData(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, FX_FLOAT x, FX_FLOAT y)
579 ASSERT(m_nChars == 0);
587 m_pCharCodes = (FX_DWORD*)(FX_UINTPTR) * pCharCodes;
589 m_pCharCodes = FX_Alloc(FX_DWORD, nChars);
590 FXSYS_memcpy32(m_pCharCodes, pCharCodes, sizeof(FX_DWORD)*nChars);
591 m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1);
592 FXSYS_memcpy32(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1));
594 RecalcPositionData();
596 void CPDF_TextObject::SetTextState(CPDF_TextState TextState)
598 m_TextState = TextState;
599 CalcPositionData(NULL, NULL, 0);
601 CPDF_ShadingObject::CPDF_ShadingObject()
604 m_Type = PDFPAGE_SHADING;
606 CPDF_ShadingObject::~CPDF_ShadingObject()
609 void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc)
611 CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc;
612 m_pShading = pSrcObj->m_pShading;
613 if (m_pShading && m_pShading->m_pDocument) {
614 CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData();
615 m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(m_pShading->m_pShadingObj, m_pShading->m_bShadingObj, &m_pShading->m_ParentMatrix);
617 m_Matrix = pSrcObj->m_Matrix;
619 void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix)
621 if (!m_ClipPath.IsNull()) {
622 m_ClipPath.GetModify();
623 m_ClipPath.Transform(matrix);
625 m_Matrix.Concat(matrix);
626 if (!m_ClipPath.IsNull()) {
629 matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
632 void CPDF_ShadingObject::CalcBoundingBox()
634 if (m_ClipPath.IsNull()) {
637 CFX_FloatRect rect = m_ClipPath.GetClipBox();
639 m_Bottom = rect.bottom;
640 m_Right = rect.right;
643 CPDF_FormObject::~CPDF_FormObject()
649 void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix)
651 m_FormMatrix.Concat(matrix);
654 void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc)
656 const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc;
660 m_pForm = pSrcObj->m_pForm->Clone();
661 m_FormMatrix = pSrcObj->m_FormMatrix;
663 void CPDF_FormObject::CalcBoundingBox()
665 CFX_FloatRect form_rect = m_pForm->CalcBoundingBox();
666 form_rect.Transform(&m_FormMatrix);
667 m_Left = form_rect.left;
668 m_Bottom = form_rect.bottom;
669 m_Right = form_rect.right;
670 m_Top = form_rect.top;
672 CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) : m_ObjectList(128)
674 m_bBackgroundAlphaNeeded = FALSE;
675 m_bReleaseMembers = bReleaseMembers;
676 m_ParseState = PDF_CONTENT_NOT_PARSED;
678 m_pFormStream = NULL;
681 CPDF_PageObjects::~CPDF_PageObjects()
686 if (!m_bReleaseMembers) {
689 FX_POSITION pos = m_ObjectList.GetHeadPosition();
691 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
694 void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause)
696 if (m_pParser == NULL) {
699 m_pParser->Continue(pPause);
700 if (m_pParser->GetStatus() == CPDF_ContentParser::Done) {
701 m_ParseState = PDF_CONTENT_PARSED;
706 int CPDF_PageObjects::EstimateParseProgress() const
708 if (m_pParser == NULL) {
709 return m_ParseState == PDF_CONTENT_PARSED ? 100 : 0;
711 return m_pParser->EstimateProgress();
713 FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, CPDF_PageObject* pNewObject)
715 if (posInsertAfter == NULL) {
716 return m_ObjectList.AddHead(pNewObject);
718 return m_ObjectList.InsertAfter(posInsertAfter, pNewObject);
721 int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const
724 FX_POSITION pos = m_ObjectList.GetHeadPosition();
726 CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
727 if (pThisObj == pObj) {
734 CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const
736 FX_POSITION pos = m_ObjectList.FindIndex(index);
740 return (CPDF_PageObject*)m_ObjectList.GetAt(pos);
742 void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix)
744 FX_POSITION pos = m_ObjectList.GetHeadPosition();
746 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
747 pObj->Transform(matrix);
750 CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const
752 if (m_ObjectList.GetCount() == 0) {
753 return CFX_FloatRect(0, 0, 0, 0);
755 FX_FLOAT left, right, top, bottom;
756 left = bottom = 1000000 * 1.0f;
757 right = top = -1000000 * 1.0f;
758 FX_POSITION pos = m_ObjectList.GetHeadPosition();
760 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
761 if (left > pObj->m_Left) {
764 if (right < pObj->m_Right) {
765 right = pObj->m_Right;
767 if (top < pObj->m_Top) {
770 if (bottom > pObj->m_Bottom) {
771 bottom = pObj->m_Bottom;
774 return CFX_FloatRect(left, bottom, right, top);
776 void CPDF_PageObjects::LoadTransInfo()
778 if (m_pFormDict == NULL) {
781 CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group"));
782 if (pGroup == NULL) {
785 if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) {
788 m_Transparency |= PDFTRANS_GROUP;
789 if (pGroup->GetInteger(FX_BSTRC("I"))) {
790 m_Transparency |= PDFTRANS_ISOLATED;
792 if (pGroup->GetInteger(FX_BSTRC("K"))) {
793 m_Transparency |= PDFTRANS_KNOCKOUT;
796 void CPDF_PageObjects::ClearCacheObjects()
798 m_ParseState = PDF_CONTENT_NOT_PARSED;
803 if (m_bReleaseMembers) {
804 FX_POSITION pos = m_ObjectList.GetHeadPosition();
806 delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
809 m_ObjectList.RemoveAll();
811 CPDF_Page::CPDF_Page()
813 m_pPageRender = NULL;
815 void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BOOL bPageCache)
817 m_pDocument = (CPDF_Document*)pDocument;
818 m_pFormDict = pPageDict;
820 m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this);
822 if (pPageDict == NULL) {
823 m_PageWidth = m_PageHeight = 100 * 1.0f;
824 m_pPageResources = m_pResources = NULL;
827 CPDF_Object* pageAttr = GetPageAttr(FX_BSTRC("Resources"));
828 m_pResources = pageAttr ? pageAttr->GetDict() : NULL;
829 m_pPageResources = m_pResources;
830 CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate"));
833 rotate = pRotate->GetInteger() / 90 % 4;
838 CPDF_Array* pMediaBox, *pCropBox;
839 pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox"));
840 CFX_FloatRect mediabox;
842 mediabox = pMediaBox->GetRect();
843 mediabox.Normalize();
845 if (mediabox.IsEmpty()) {
846 mediabox = CFX_FloatRect(0, 0, 612, 792);
848 pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox"));
850 m_BBox = pCropBox->GetRect();
853 if (m_BBox.IsEmpty()) {
856 m_BBox.Intersect(mediabox);
859 m_PageHeight = m_BBox.right - m_BBox.left;
860 m_PageWidth = m_BBox.top - m_BBox.bottom;
862 m_PageWidth = m_BBox.right - m_BBox.left;
863 m_PageHeight = m_BBox.top - m_BBox.bottom;
867 m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom);
870 m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right);
873 m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top);
876 m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left);
879 m_Transparency = PDFTRANS_ISOLATED;
882 void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
887 if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
890 m_pParser = new CPDF_ContentParser;
891 m_pParser->Start(this, pOptions);
892 m_ParseState = PDF_CONTENT_PARSING;
894 void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
896 StartParse(pOptions, bReParse);
899 CPDF_Page::~CPDF_Page()
902 CPDF_RenderModuleDef* pModule = CPDF_ModuleMgr::Get()->GetRenderModule();
903 pModule->DestroyPageCache(m_pPageRender);
906 CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, FX_BSTR name)
910 CPDF_Object* pObj = pPageDict->GetElementValue(name);
914 CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent"));
915 if (!pParent || pParent == pPageDict) {
925 CPDF_Object* CPDF_Page::GetPageAttr(FX_BSTR name) const
927 return FPDFAPI_GetPageAttr(m_pFormDict, name);
929 CPDF_Form::CPDF_Form(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Stream* pFormStream, CPDF_Dictionary* pParentResources)
932 m_pFormStream = pFormStream;
933 m_pFormDict = pFormStream ? pFormStream->GetDict() : NULL;
934 m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources"));
935 m_pPageResources = pPageResources;
936 if (m_pResources == NULL) {
937 m_pResources = pParentResources;
939 if (m_pResources == NULL) {
940 m_pResources = pPageResources;
945 CPDF_Form::~CPDF_Form()
948 void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
949 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
951 if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
954 m_pParser = new CPDF_ContentParser;
955 m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
956 m_ParseState = PDF_CONTENT_PARSING;
958 void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
959 CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
961 StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
964 CPDF_Form* CPDF_Form::Clone() const
966 CPDF_Form* pClone = new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources);
967 FX_POSITION pos = m_ObjectList.GetHeadPosition();
969 CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
970 pClone->m_ObjectList.AddTail(pObj->Clone());
974 void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos,
975 int xSize, int ySize, int iRotate) const
977 if (m_PageWidth == 0 || m_PageHeight == 0) {
980 CFX_AffineMatrix display_matrix;
981 int x0, y0, x1, y1, x2, y2;
1017 display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth),
1018 FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth),
1019 FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight),
1020 FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight),
1021 (FX_FLOAT)x0, (FX_FLOAT)y0);
1022 matrix = m_PageMatrix;
1023 matrix.Concat(display_matrix);
1025 CPDF_ParseOptions::CPDF_ParseOptions()
1027 m_bTextOnly = FALSE;
1028 m_bMarkedContent = TRUE;
1029 m_bSeparateForm = TRUE;
1030 m_bDecodeInlineImage = FALSE;