Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfdoc/include/cpdf_annot.h" | 7 #include "core/fpdfdoc/include/cpdf_annot.h" |
| 8 | 8 |
| 9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" | 9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" |
| 10 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" | 10 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" |
| 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" | 13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" |
| 14 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" | 14 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" |
| 15 #include "core/fpdfdoc/cpvt_generateap.h" | 15 #include "core/fpdfdoc/cpvt_generateap.h" |
| 16 #include "core/fxcrt/include/fx_memory.h" | 16 #include "core/fxcrt/include/fx_memory.h" |
| 17 #include "core/fxge/include/cfx_graphstatedata.h" | 17 #include "core/fxge/include/cfx_graphstatedata.h" |
| 18 #include "core/fxge/include/cfx_pathdata.h" | 18 #include "core/fxge/include/cfx_pathdata.h" |
| 19 #include "core/fxge/include/cfx_renderdevice.h" | 19 #include "core/fxge/include/cfx_renderdevice.h" |
| 20 | 20 |
| 21 namespace { | |
|
Lei Zhang
2016/09/01 21:12:59
When not forward declaring, add blank lines after
tonikitoo
2016/09/01 21:50:41
Done.
| |
| 22 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) { | |
| 23 // If AP dictionary exists, we use the appearance defined in the | |
| 24 // existing AP dictionary. | |
| 25 if (pAnnotDict->KeyExist("AP")) | |
| 26 return false; | |
| 27 | |
| 28 return !CPDF_Annot::IsAnnotationHidden(pAnnotDict); | |
| 29 } | |
| 30 } // namespace | |
| 31 | |
| 21 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_Document* pDocument) | 32 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_Document* pDocument) |
| 22 : m_pAnnotDict(pDict), | 33 : m_pAnnotDict(pDict), |
| 23 m_pDocument(pDocument), | 34 m_pDocument(pDocument), |
| 24 m_bOpenState(false), | 35 m_bOpenState(false), |
| 36 m_bHasGeneratedAP(false), | |
| 25 m_pPopupAnnot(nullptr) { | 37 m_pPopupAnnot(nullptr) { |
| 26 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringBy("Subtype")); | 38 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringBy("Subtype")); |
| 27 GenerateAPIfNeeded(); | 39 GenerateAPIfNeeded(); |
| 28 } | 40 } |
| 29 | 41 |
| 30 CPDF_Annot::~CPDF_Annot() { | 42 CPDF_Annot::~CPDF_Annot() { |
| 31 ClearCachedAP(); | 43 ClearCachedAP(); |
| 32 } | 44 } |
| 33 | 45 |
| 34 void CPDF_Annot::GenerateAPIfNeeded() { | 46 void CPDF_Annot::GenerateAPIfNeeded() { |
| 47 if (!ShouldGenerateAPForAnnotation(m_pAnnotDict)) | |
| 48 return; | |
| 49 | |
| 50 bool result = false; | |
| 35 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE) | 51 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE) |
| 36 CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); | 52 result = CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); |
| 37 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) | 53 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) |
| 38 CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); | 54 result = CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); |
| 39 else if (m_nSubtype == CPDF_Annot::Subtype::INK) | 55 else if (m_nSubtype == CPDF_Annot::Subtype::INK) |
| 40 CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); | 56 result = CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); |
| 41 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP) | 57 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP) |
| 42 CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); | 58 result = CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); |
| 43 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE) | 59 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE) |
| 44 CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); | 60 result = CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); |
| 45 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY) | 61 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY) |
| 46 CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); | 62 result = CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); |
| 47 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT) | 63 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT) |
| 48 CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); | 64 result = CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); |
| 49 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT) | 65 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT) |
| 50 CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); | 66 result = CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); |
| 51 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE) | 67 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE) |
| 52 CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); | 68 result = CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); |
| 69 m_bHasGeneratedAP = result; | |
| 53 } | 70 } |
| 54 | 71 |
| 55 void CPDF_Annot::ClearCachedAP() { | 72 void CPDF_Annot::ClearCachedAP() { |
| 56 m_APMap.clear(); | 73 m_APMap.clear(); |
| 57 } | 74 } |
| 58 | 75 |
| 59 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const { | 76 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const { |
| 60 return m_nSubtype; | 77 return m_nSubtype; |
| 61 } | 78 } |
| 62 | 79 |
| 80 bool CPDF_Annot::ShouldUseQuadPointsCoords(CPDF_Array*& pArray) const { | |
|
Tom Sepez
2016/09/01 20:53:08
nit: can we make this a CPDF_Array** argument, sin
tonikitoo
2016/09/01 21:50:41
Done.
| |
| 81 if (!m_pAnnotDict) | |
| 82 return false; | |
| 83 | |
| 84 pArray = m_pAnnotDict->GetArrayBy("QuadPoints"); | |
| 85 if (!pArray) | |
| 86 return false; | |
| 87 | |
| 88 return m_bHasGeneratedAP; | |
| 89 } | |
| 90 | |
| 63 CFX_FloatRect CPDF_Annot::GetRect() const { | 91 CFX_FloatRect CPDF_Annot::GetRect() const { |
| 64 if (!m_pAnnotDict) | 92 if (!m_pAnnotDict) |
| 65 return CFX_FloatRect(); | 93 return CFX_FloatRect(); |
| 66 | 94 |
| 67 CFX_FloatRect rect = m_pAnnotDict->GetRectBy("Rect"); | 95 CFX_FloatRect rect; |
| 96 CPDF_Array* pArray = nullptr; | |
| 97 if (ShouldUseQuadPointsCoords(pArray)) { | |
| 98 // QuadPoints are defined with 4 pairs of numbers | |
| 99 // ([ pair0, pair1, pair2, pair3 ]), where | |
| 100 // pair0= top_left | |
|
Lei Zhang
2016/09/01 21:12:59
add a space before '=', to be consistent with line
tonikitoo
2016/09/01 21:50:41
Done.
| |
| 101 // pair1= top_right | |
| 102 // pair2= bottom_left | |
| 103 // pair3= bottom_right | |
| 104 // | |
| 105 // On the other hand, /Rect is define as 2 pairs [pair0, pair1] where: | |
| 106 // pair0 = bottom_left | |
| 107 // pair1 = top_right. | |
| 108 rect = CFX_FloatRect(pArray->GetNumberAt(4), pArray->GetNumberAt(5), | |
| 109 pArray->GetNumberAt(2), pArray->GetNumberAt(3)); | |
| 110 } else { | |
| 111 rect = m_pAnnotDict->GetRectBy("Rect"); | |
| 112 } | |
| 113 | |
|
jaepark
2016/09/01 20:52:00
Even if we changed the rect for CPDF_Annot::GetRec
tonikitoo
2016/09/01 21:50:41
This is a good point. I will check further how the
| |
| 68 rect.Normalize(); | 114 rect.Normalize(); |
| 69 return rect; | 115 return rect; |
| 70 } | 116 } |
| 71 | 117 |
| 72 uint32_t CPDF_Annot::GetFlags() const { | 118 uint32_t CPDF_Annot::GetFlags() const { |
| 73 return m_pAnnotDict->GetIntegerBy("F"); | 119 return m_pAnnotDict->GetIntegerBy("F"); |
| 74 } | 120 } |
| 75 | 121 |
| 76 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, | 122 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, |
| 77 CPDF_Annot::AppearanceMode mode) { | 123 CPDF_Annot::AppearanceMode mode) { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 CFX_PathData path; | 448 CFX_PathData path; |
| 403 width /= 2; | 449 width /= 2; |
| 404 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, | 450 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, |
| 405 rect.top - width); | 451 rect.top - width); |
| 406 int fill_type = 0; | 452 int fill_type = 0; |
| 407 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { | 453 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { |
| 408 fill_type |= FXFILL_NOPATHSMOOTH; | 454 fill_type |= FXFILL_NOPATHSMOOTH; |
| 409 } | 455 } |
| 410 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); | 456 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); |
| 411 } | 457 } |
| OLD | NEW |