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

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

Issue 2289293005: Use /RECT or /QuadPoints for annotation coordinates, depending on /AP (Closed)
Patch Set: addressed thestig's comments 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 | « no previous file | core/fpdfdoc/cpvt_generateap.cpp » ('j') | core/fpdfdoc/cpvt_generateap.cpp » ('J')
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 bool IsTextMarkupAnnotation(CPDF_Annot::Subtype type) {
24 return type == CPDF_Annot::Subtype::HIGHLIGHT ||
25 type == CPDF_Annot::Subtype::SQUIGGLY ||
26 type == CPDF_Annot::Subtype::STRIKEOUT ||
27 type == CPDF_Annot::Subtype::UNDERLINE;
28 }
29
23 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) { 30 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) {
24 // If AP dictionary exists, we use the appearance defined in the 31 // If AP dictionary exists, we use the appearance defined in the
25 // existing AP dictionary. 32 // existing AP dictionary.
26 if (pAnnotDict->KeyExist("AP")) 33 if (pAnnotDict->KeyExist("AP"))
27 return false; 34 return false;
28 35
29 return !CPDF_Annot::IsAnnotationHidden(pAnnotDict); 36 return !CPDF_Annot::IsAnnotationHidden(pAnnotDict);
30 } 37 }
31 38
32 } // namespace 39 } // namespace
33 40
34 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, 41 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict,
35 CPDF_Document* pDocument, 42 CPDF_Document* pDocument,
36 bool bToOwnDict) 43 bool bToOwnDict)
37 : m_bOwnedAnnotDict(bToOwnDict), 44 : m_bOwnedAnnotDict(bToOwnDict),
38 m_pAnnotDict(pDict), 45 m_pAnnotDict(pDict),
39 m_pDocument(pDocument), 46 m_pDocument(pDocument),
40 m_bOpenState(false), 47 m_bOpenState(false),
48 m_bHasGeneratedAP(false),
41 m_pPopupAnnot(nullptr) { 49 m_pPopupAnnot(nullptr) {
42 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringBy("Subtype")); 50 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringBy("Subtype"));
51 m_bIsMarkupAnnotation = IsTextMarkupAnnotation(m_nSubtype);
jaepark 2016/09/07 17:30:09 m_bIsTextMarkupAnnotation
tonikitoo 2016/09/08 04:10:35 Done.
43 GenerateAPIfNeeded(); 52 GenerateAPIfNeeded();
44 } 53 }
45 54
46 CPDF_Annot::~CPDF_Annot() { 55 CPDF_Annot::~CPDF_Annot() {
47 if (m_bOwnedAnnotDict) 56 if (m_bOwnedAnnotDict)
48 m_pAnnotDict->Release(); 57 m_pAnnotDict->Release();
49 ClearCachedAP(); 58 ClearCachedAP();
50 } 59 }
51 60
52 void CPDF_Annot::GenerateAPIfNeeded() { 61 void CPDF_Annot::GenerateAPIfNeeded() {
53 if (!ShouldGenerateAPForAnnotation(m_pAnnotDict)) 62 if (!ShouldGenerateAPForAnnotation(m_pAnnotDict))
54 return; 63 return;
55 64
65 bool result = false;
56 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE) 66 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE)
57 CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); 67 result = CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict);
58 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) 68 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT)
59 CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); 69 result = CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict);
60 else if (m_nSubtype == CPDF_Annot::Subtype::INK) 70 else if (m_nSubtype == CPDF_Annot::Subtype::INK)
61 CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); 71 result = CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict);
62 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP) 72 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP)
63 CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); 73 result = CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict);
64 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE) 74 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE)
65 CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); 75 result = CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict);
66 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY) 76 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY)
67 CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); 77 result = CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict);
68 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT) 78 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT)
69 CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); 79 result = CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict);
70 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT) 80 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT)
71 CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); 81 result = CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict);
72 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE) 82 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE)
73 CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); 83 result = CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict);
84 m_bHasGeneratedAP = result;
74 } 85 }
75 86
76 void CPDF_Annot::ClearCachedAP() { 87 void CPDF_Annot::ClearCachedAP() {
77 m_APMap.clear(); 88 m_APMap.clear();
78 } 89 }
79 90
80 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const { 91 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const {
81 return m_nSubtype; 92 return m_nSubtype;
82 } 93 }
83 94
95 CFX_FloatRect CPDF_Annot::RectForDrawing() const {
96 if (!m_pAnnotDict)
97 return CFX_FloatRect();
98
99 bool shouldUseQuadPointsCoords = m_bIsMarkupAnnotation && m_bHasGeneratedAP;
jaepark 2016/09/07 17:30:09 To me, checking m_bHasGeneratedAP in RectForDrawin
tonikitoo 2016/09/08 04:10:35 Checking for m_bHasGeneratedAP is important here b
jaepark 2016/09/08 17:49:27 Acknowledged.
100 if (shouldUseQuadPointsCoords)
101 return RectFromQuads(m_pAnnotDict);
102
103 return m_pAnnotDict->GetRectBy("Rect");
104 }
105
84 CFX_FloatRect CPDF_Annot::GetRect() const { 106 CFX_FloatRect CPDF_Annot::GetRect() const {
85 if (!m_pAnnotDict) 107 if (!m_pAnnotDict)
86 return CFX_FloatRect(); 108 return CFX_FloatRect();
87 109
88 CFX_FloatRect rect = m_pAnnotDict->GetRectBy("Rect"); 110 CFX_FloatRect rect = RectForDrawing();
89 rect.Normalize(); 111 rect.Normalize();
90 return rect; 112 return rect;
91 } 113 }
92 114
93 uint32_t CPDF_Annot::GetFlags() const { 115 uint32_t CPDF_Annot::GetFlags() const {
94 return m_pAnnotDict->GetIntegerBy("F"); 116 return m_pAnnotDict->GetIntegerBy("F");
95 } 117 }
96 118
97 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, 119 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
98 CPDF_Annot::AppearanceMode mode) { 120 CPDF_Annot::AppearanceMode mode) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 181 }
160 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRectBy("BBox"); 182 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRectBy("BBox");
161 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixBy("Matrix"); 183 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixBy("Matrix");
162 form_matrix.TransformRect(form_bbox); 184 form_matrix.TransformRect(form_bbox);
163 matrix.MatchRect(pAnnot->GetRect(), form_bbox); 185 matrix.MatchRect(pAnnot->GetRect(), form_bbox);
164 matrix.Concat(*pUser2Device); 186 matrix.Concat(*pUser2Device);
165 return pForm; 187 return pForm;
166 } 188 }
167 189
168 // Static. 190 // Static.
191 CFX_FloatRect CPDF_Annot::RectFromQuads(CPDF_Dictionary* pAnnotDict) {
jaepark 2016/09/07 17:30:09 RectFromQuadPoints
tonikitoo 2016/09/08 04:10:35 Done.
192 CPDF_Array* pArray = pAnnotDict->GetArrayBy("QuadPoints");
193 if (!pArray)
194 return CFX_FloatRect();
195
196 // QuadPoints are defined with 4 pairs of numbers
197 // ([ pair0, pair1, pair2, pair3 ]), where
198 // pair0 = top_left
199 // pair1 = top_right
200 // pair2 = bottom_left
201 // pair3 = bottom_right
202 //
203 // On the other hand, /Rect is define as 2 pairs [pair0, pair1] where:
204 // pair0 = bottom_left
205 // pair1 = top_right.
206 return CFX_FloatRect(pArray->GetNumberAt(4), pArray->GetNumberAt(5),
207 pArray->GetNumberAt(2), pArray->GetNumberAt(3));
208 }
209
210 // Static.
169 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) { 211 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) {
170 return !!(pAnnotDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN); 212 return !!(pAnnotDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN);
171 } 213 }
172 214
173 // Static. 215 // Static.
174 CPDF_Annot::Subtype CPDF_Annot::StringToAnnotSubtype( 216 CPDF_Annot::Subtype CPDF_Annot::StringToAnnotSubtype(
175 const CFX_ByteString& sSubtype) { 217 const CFX_ByteString& sSubtype) {
176 if (sSubtype == "Text") 218 if (sSubtype == "Text")
177 return CPDF_Annot::Subtype::TEXT; 219 return CPDF_Annot::Subtype::TEXT;
178 if (sSubtype == "Link") 220 if (sSubtype == "Link")
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 CFX_PathData path; 465 CFX_PathData path;
424 width /= 2; 466 width /= 2;
425 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, 467 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width,
426 rect.top - width); 468 rect.top - width);
427 int fill_type = 0; 469 int fill_type = 0;
428 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { 470 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) {
429 fill_type |= FXFILL_NOPATHSMOOTH; 471 fill_type |= FXFILL_NOPATHSMOOTH;
430 } 472 }
431 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); 473 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type);
432 } 474 }
OLDNEW
« no previous file with comments | « no previous file | core/fpdfdoc/cpvt_generateap.cpp » ('j') | core/fpdfdoc/cpvt_generateap.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698