Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: core/fpdfdoc/cpdf_annot.cpp

Issue 2289293005: Use /RECT or /QuadPoints for annotation coordinates, depending on /AP (Closed)
Patch Set: rebased + new DEPS Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « DEPS ('k') | core/fpdfdoc/cpvt_generateap.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 { 21 namespace {
22 22
23 char kPDFiumKey_HasGeneratedAP[] = "PDFIUM_HasGeneratedAP";
24
25 bool IsTextMarkupAnnotation(CPDF_Annot::Subtype type) {
26 return type == CPDF_Annot::Subtype::HIGHLIGHT ||
27 type == CPDF_Annot::Subtype::SQUIGGLY ||
28 type == CPDF_Annot::Subtype::STRIKEOUT ||
29 type == CPDF_Annot::Subtype::UNDERLINE;
30 }
31
23 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) { 32 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) {
24 // If AP dictionary exists, we use the appearance defined in the 33 // If AP dictionary exists, we use the appearance defined in the
25 // existing AP dictionary. 34 // existing AP dictionary.
26 if (pAnnotDict->KeyExist("AP")) 35 if (pAnnotDict->KeyExist("AP"))
27 return false; 36 return false;
28 37
29 return !CPDF_Annot::IsAnnotationHidden(pAnnotDict); 38 return !CPDF_Annot::IsAnnotationHidden(pAnnotDict);
30 } 39 }
31 40
32 } // namespace 41 } // namespace
33 42
34 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, 43 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict,
35 CPDF_Document* pDocument, 44 CPDF_Document* pDocument,
36 bool bToOwnDict) 45 bool bToOwnDict)
37 : m_bOwnedAnnotDict(bToOwnDict), 46 : m_bOwnedAnnotDict(bToOwnDict),
38 m_pAnnotDict(pDict), 47 m_pAnnotDict(pDict),
39 m_pDocument(pDocument), 48 m_pDocument(pDocument),
40 m_bOpenState(false), 49 m_bOpenState(false),
41 m_pPopupAnnot(nullptr) { 50 m_pPopupAnnot(nullptr) {
42 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringFor("Subtype")); 51 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringFor("Subtype"));
52 m_bIsTextMarkupAnnotation = IsTextMarkupAnnotation(m_nSubtype);
53 m_bHasGeneratedAP = m_pAnnotDict->GetBooleanFor(kPDFiumKey_HasGeneratedAP);
43 GenerateAPIfNeeded(); 54 GenerateAPIfNeeded();
44 } 55 }
45 56
46 CPDF_Annot::~CPDF_Annot() { 57 CPDF_Annot::~CPDF_Annot() {
47 if (m_bOwnedAnnotDict) 58 if (m_bOwnedAnnotDict)
48 m_pAnnotDict->Release(); 59 m_pAnnotDict->Release();
49 ClearCachedAP(); 60 ClearCachedAP();
50 } 61 }
51 62
52 void CPDF_Annot::GenerateAPIfNeeded() { 63 void CPDF_Annot::GenerateAPIfNeeded() {
53 if (!ShouldGenerateAPForAnnotation(m_pAnnotDict)) 64 if (!ShouldGenerateAPForAnnotation(m_pAnnotDict))
54 return; 65 return;
55 66
67 bool result = false;
56 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE) 68 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE)
57 CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); 69 result = CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict);
58 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) 70 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT)
59 CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); 71 result = CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict);
60 else if (m_nSubtype == CPDF_Annot::Subtype::INK) 72 else if (m_nSubtype == CPDF_Annot::Subtype::INK)
61 CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); 73 result = CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict);
62 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP) 74 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP)
63 CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); 75 result = CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict);
64 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE) 76 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE)
65 CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); 77 result = CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict);
66 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY) 78 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY)
67 CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); 79 result = CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict);
68 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT) 80 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT)
69 CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); 81 result = CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict);
70 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT) 82 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT)
71 CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); 83 result = CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict);
72 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE) 84 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE)
73 CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); 85 result = CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict);
86
87 if (result) {
88 m_pAnnotDict->SetBooleanFor(kPDFiumKey_HasGeneratedAP, result);
89 m_bHasGeneratedAP = result;
90 }
74 } 91 }
75 92
76 bool CPDF_Annot::ShouldDrawAnnotation() { 93 bool CPDF_Annot::ShouldDrawAnnotation() {
77 if (IsAnnotationHidden(m_pAnnotDict)) 94 if (IsAnnotationHidden(m_pAnnotDict))
78 return false; 95 return false;
79 96
80 if (m_nSubtype == CPDF_Annot::Subtype::POPUP && !m_bOpenState) 97 if (m_nSubtype == CPDF_Annot::Subtype::POPUP && !m_bOpenState)
81 return false; 98 return false;
82 99
83 return true; 100 return true;
84 } 101 }
85 102
86 void CPDF_Annot::ClearCachedAP() { 103 void CPDF_Annot::ClearCachedAP() {
87 m_APMap.clear(); 104 m_APMap.clear();
88 } 105 }
89 106
90 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const { 107 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const {
91 return m_nSubtype; 108 return m_nSubtype;
92 } 109 }
93 110
111 CFX_FloatRect CPDF_Annot::RectForDrawing() const {
112 if (!m_pAnnotDict)
113 return CFX_FloatRect();
114
115 bool bShouldUseQuadPointsCoords =
116 m_bIsTextMarkupAnnotation && m_bHasGeneratedAP;
117 if (bShouldUseQuadPointsCoords)
118 return RectFromQuadPoints(m_pAnnotDict);
119
120 return m_pAnnotDict->GetRectFor("Rect");
121 }
122
94 CFX_FloatRect CPDF_Annot::GetRect() const { 123 CFX_FloatRect CPDF_Annot::GetRect() const {
95 if (!m_pAnnotDict) 124 if (!m_pAnnotDict)
96 return CFX_FloatRect(); 125 return CFX_FloatRect();
97 126
98 CFX_FloatRect rect = m_pAnnotDict->GetRectFor("Rect"); 127 CFX_FloatRect rect = RectForDrawing();
99 rect.Normalize(); 128 rect.Normalize();
100 return rect; 129 return rect;
101 } 130 }
102 131
103 uint32_t CPDF_Annot::GetFlags() const { 132 uint32_t CPDF_Annot::GetFlags() const {
104 return m_pAnnotDict->GetIntegerFor("F"); 133 return m_pAnnotDict->GetIntegerFor("F");
105 } 134 }
106 135
107 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, 136 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
108 CPDF_Annot::AppearanceMode mode) { 137 CPDF_Annot::AppearanceMode mode) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 198 }
170 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRectFor("BBox"); 199 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRectFor("BBox");
171 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix"); 200 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix");
172 form_matrix.TransformRect(form_bbox); 201 form_matrix.TransformRect(form_bbox);
173 matrix.MatchRect(pAnnot->GetRect(), form_bbox); 202 matrix.MatchRect(pAnnot->GetRect(), form_bbox);
174 matrix.Concat(*pUser2Device); 203 matrix.Concat(*pUser2Device);
175 return pForm; 204 return pForm;
176 } 205 }
177 206
178 // Static. 207 // Static.
208 CFX_FloatRect CPDF_Annot::RectFromQuadPoints(CPDF_Dictionary* pAnnotDict) {
209 CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints");
210 if (!pArray)
211 return CFX_FloatRect();
212
213 // QuadPoints are defined with 4 pairs of numbers
214 // ([ pair0, pair1, pair2, pair3 ]), where
215 // pair0 = top_left
216 // pair1 = top_right
217 // pair2 = bottom_left
218 // pair3 = bottom_right
219 //
220 // On the other hand, /Rect is define as 2 pairs [pair0, pair1] where:
221 // pair0 = bottom_left
222 // pair1 = top_right.
223 return CFX_FloatRect(pArray->GetNumberAt(4), pArray->GetNumberAt(5),
224 pArray->GetNumberAt(2), pArray->GetNumberAt(3));
225 }
226
227 // Static.
179 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) { 228 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) {
180 return !!(pAnnotDict->GetIntegerFor("F") & ANNOTFLAG_HIDDEN); 229 return !!(pAnnotDict->GetIntegerFor("F") & ANNOTFLAG_HIDDEN);
181 } 230 }
182 231
183 // Static. 232 // Static.
184 CPDF_Annot::Subtype CPDF_Annot::StringToAnnotSubtype( 233 CPDF_Annot::Subtype CPDF_Annot::StringToAnnotSubtype(
185 const CFX_ByteString& sSubtype) { 234 const CFX_ByteString& sSubtype) {
186 if (sSubtype == "Text") 235 if (sSubtype == "Text")
187 return CPDF_Annot::Subtype::TEXT; 236 return CPDF_Annot::Subtype::TEXT;
188 if (sSubtype == "Link") 237 if (sSubtype == "Link")
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 CFX_PathData path; 489 CFX_PathData path;
441 width /= 2; 490 width /= 2;
442 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, 491 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width,
443 rect.top - width); 492 rect.top - width);
444 int fill_type = 0; 493 int fill_type = 0;
445 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { 494 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) {
446 fill_type |= FXFILL_NOPATHSMOOTH; 495 fill_type |= FXFILL_NOPATHSMOOTH;
447 } 496 }
448 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); 497 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type);
449 } 498 }
OLDNEW
« no previous file with comments | « DEPS ('k') | core/fpdfdoc/cpvt_generateap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698