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 |