OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium 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 #include "pdf/pdfium/pdfium_page.h" | 5 #include "pdf/pdfium/pdfium_page.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), left, top); | 168 FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), left, top); |
169 Area area; | 169 Area area; |
170 std::vector<LinkTarget> targets; | 170 std::vector<LinkTarget> targets; |
171 if (link) { | 171 if (link) { |
172 targets.push_back(LinkTarget()); | 172 targets.push_back(LinkTarget()); |
173 area = GetLinkTarget(link, &targets[0]); | 173 area = GetLinkTarget(link, &targets[0]); |
174 } else { | 174 } else { |
175 pp::Rect rect( | 175 pp::Rect rect( |
176 PageToScreen(pp::Point(), 1.0, left, top, right, bottom, rotation)); | 176 PageToScreen(pp::Point(), 1.0, left, top, right, bottom, rotation)); |
177 GetLinks(rect, &targets); | 177 GetLinks(rect, &targets); |
178 area = targets.size() == 0 ? TEXT_AREA : WEBLINK_AREA; | 178 area = targets.empty() ? TEXT_AREA : WEBLINK_AREA; |
179 } | 179 } |
180 | 180 |
181 int char_index = FPDFText_GetCharIndexAtPos(GetTextPage(), left, top, | 181 int char_index = FPDFText_GetCharIndexAtPos(GetTextPage(), left, top, |
182 kTolerance, kTolerance); | 182 kTolerance, kTolerance); |
183 double font_size = FPDFText_GetFontSize(GetTextPage(), char_index); | 183 double font_size = FPDFText_GetFontSize(GetTextPage(), char_index); |
184 | 184 |
185 base::DictionaryValue* node = new base::DictionaryValue(); | 185 base::DictionaryValue* node = new base::DictionaryValue(); |
186 node->SetDouble(kTextBoxLeft, left); | 186 node->SetDouble(kTextBoxLeft, left); |
187 node->SetDouble(kTextBoxTop, page_height - top); | 187 node->SetDouble(kTextBoxTop, page_height - top); |
188 node->SetDouble(kTextBoxWidth, right - left); | 188 node->SetDouble(kTextBoxWidth, right - left); |
189 node->SetDouble(kTextBoxHeight, top - bottom); | 189 node->SetDouble(kTextBoxHeight, top - bottom); |
190 node->SetDouble(kTextBoxFontSize, font_size); | 190 node->SetDouble(kTextBoxFontSize, font_size); |
191 | 191 |
192 base::ListValue* text_nodes = new base::ListValue(); | 192 base::ListValue* text_nodes = new base::ListValue(); |
193 | 193 |
194 if (area == DOCLINK_AREA) { | 194 if (area == DOCLINK_AREA) { |
195 std::string url = kDocLinkURLPrefix + base::IntToString(targets[0].page); | 195 std::string url = kDocLinkURLPrefix + base::IntToString(targets[0].page); |
196 text_nodes->Append(CreateURLNode(text_utf8, url)); | 196 text_nodes->Append(CreateURLNode(text_utf8, url)); |
197 } else if (area == WEBLINK_AREA && link) { | 197 } else if (area == WEBLINK_AREA && link) { |
198 text_nodes->Append(CreateURLNode(text_utf8, targets[0].url)); | 198 text_nodes->Append(CreateURLNode(text_utf8, targets[0].url)); |
199 } else if (area == WEBLINK_AREA && !link) { | 199 } else if (area == WEBLINK_AREA && !link) { |
200 size_t start = 0; | 200 size_t start = 0; |
201 for (size_t i = 0; i < targets.size(); ++i) { | 201 for (const auto& target : targets) { |
202 // If there is an extra NULL character at end, find() will not return any | 202 // If there is an extra NULL character at end, find() will not return any |
203 // matches. There should not be any though. | 203 // matches. There should not be any though. |
204 if (!targets[i].url.empty()) | 204 if (!target.url.empty()) |
205 DCHECK(targets[i].url[targets[i].url.size() - 1] != '\0'); | 205 DCHECK_NE(target.url.back(), '\0'); |
206 | 206 |
207 // PDFium may change the case of generated links. | 207 // PDFium may change the case of generated links. |
208 std::string lowerCaseURL = base::ToLowerASCII(targets[i].url); | 208 std::string lowerCaseURL = base::ToLowerASCII(target.url); |
209 std::string lowerCaseText = base::ToLowerASCII(text_utf8); | 209 std::string lowerCaseText = base::ToLowerASCII(text_utf8); |
210 size_t pos = lowerCaseText.find(lowerCaseURL, start); | 210 size_t pos = lowerCaseText.find(lowerCaseURL, start); |
211 size_t length = targets[i].url.size(); | 211 size_t length = target.url.size(); |
212 if (pos == std::string::npos) { | 212 if (pos == std::string::npos) { |
213 // Check if the link is a "mailto:" URL | 213 // Check if the link is a "mailto:" URL |
214 if (lowerCaseURL.compare(0, 7, "mailto:") == 0) { | 214 if (lowerCaseURL.compare(0, 7, "mailto:") == 0) { |
215 pos = lowerCaseText.find(lowerCaseURL.substr(7), start); | 215 pos = lowerCaseText.find(lowerCaseURL.substr(7), start); |
216 length -= 7; | 216 length -= 7; |
217 } | 217 } |
218 | 218 |
219 if (pos == std::string::npos) { | 219 if (pos == std::string::npos) { |
220 // No match has been found. This should never happen. | 220 // No match has been found. This should never happen. |
221 continue; | 221 continue; |
222 } | 222 } |
223 } | 223 } |
224 | 224 |
225 std::string before_text = text_utf8.substr(start, pos - start); | 225 std::string before_text = text_utf8.substr(start, pos - start); |
226 if (before_text.size() > 0) | 226 if (!before_text.empty()) |
227 text_nodes->Append(CreateTextNode(before_text)); | 227 text_nodes->Append(CreateTextNode(before_text)); |
228 std::string link_text = text_utf8.substr(pos, length); | 228 std::string link_text = text_utf8.substr(pos, length); |
229 text_nodes->Append(CreateURLNode(link_text, targets[i].url)); | 229 text_nodes->Append(CreateURLNode(link_text, target.url)); |
230 | 230 |
231 start = pos + length; | 231 start = pos + length; |
232 } | 232 } |
233 std::string before_text = text_utf8.substr(start); | 233 std::string before_text = text_utf8.substr(start); |
234 if (before_text.size() > 0) | 234 if (!before_text.empty()) |
235 text_nodes->Append(CreateTextNode(before_text)); | 235 text_nodes->Append(CreateTextNode(before_text)); |
236 } else { | 236 } else { |
237 text_nodes->Append(CreateTextNode(text_utf8)); | 237 text_nodes->Append(CreateTextNode(text_utf8)); |
238 } | 238 } |
239 | 239 |
240 node->Set(kTextBoxNodes, text_nodes); // Takes ownership of |text_nodes|. | 240 node->Set(kTextBoxNodes, text_nodes); // Takes ownership of |text_nodes|. |
241 return node; | 241 return node; |
242 } | 242 } |
243 | 243 |
244 base::Value* PDFiumPage::CreateTextNode(const std::string& text) { | 244 base::Value* PDFiumPage::CreateTextNode(const std::string& text) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 return static_cast<base::char16>(FPDFText_GetUnicode(GetTextPage(), index)); | 321 return static_cast<base::char16>(FPDFText_GetUnicode(GetTextPage(), index)); |
322 } | 322 } |
323 | 323 |
324 int PDFiumPage::GetCharCount() { | 324 int PDFiumPage::GetCharCount() { |
325 if (!available_) | 325 if (!available_) |
326 return 0; | 326 return 0; |
327 return FPDFText_CountChars(GetTextPage()); | 327 return FPDFText_CountChars(GetTextPage()); |
328 } | 328 } |
329 | 329 |
330 PDFiumPage::Area PDFiumPage::GetLinkTarget( | 330 PDFiumPage::Area PDFiumPage::GetLinkTarget( |
331 FPDF_LINK link, PDFiumPage::LinkTarget* target) { | 331 FPDF_LINK link, PDFiumPage::LinkTarget* target) const { |
332 FPDF_DEST dest = FPDFLink_GetDest(engine_->doc(), link); | 332 FPDF_DEST dest = FPDFLink_GetDest(engine_->doc(), link); |
333 if (dest != NULL) | 333 if (dest) |
334 return GetDestinationTarget(dest, target); | 334 return GetDestinationTarget(dest, target); |
335 | 335 |
336 FPDF_ACTION action = FPDFLink_GetAction(link); | 336 FPDF_ACTION action = FPDFLink_GetAction(link); |
337 if (action) { | 337 if (action) { |
338 switch (FPDFAction_GetType(action)) { | 338 switch (FPDFAction_GetType(action)) { |
339 case PDFACTION_GOTO: { | 339 case PDFACTION_GOTO: { |
340 FPDF_DEST dest = FPDFAction_GetDest(engine_->doc(), action); | 340 FPDF_DEST dest = FPDFAction_GetDest(engine_->doc(), action); |
341 if (dest) | 341 if (dest) |
342 return GetDestinationTarget(dest, target); | 342 return GetDestinationTarget(dest, target); |
343 // TODO(gene): We don't fully support all types of the in-document | 343 // TODO(gene): We don't fully support all types of the in-document |
(...skipping 17 matching lines...) Expand all Loading... |
361 } break; | 361 } break; |
362 // TODO(gene): We don't support PDFACTION_REMOTEGOTO and PDFACTION_LAUNCH | 362 // TODO(gene): We don't support PDFACTION_REMOTEGOTO and PDFACTION_LAUNCH |
363 // at the moment. | 363 // at the moment. |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 return NONSELECTABLE_AREA; | 367 return NONSELECTABLE_AREA; |
368 } | 368 } |
369 | 369 |
370 PDFiumPage::Area PDFiumPage::GetDestinationTarget( | 370 PDFiumPage::Area PDFiumPage::GetDestinationTarget( |
371 FPDF_DEST destination, PDFiumPage::LinkTarget* target) { | 371 FPDF_DEST destination, PDFiumPage::LinkTarget* target) const { |
372 int page_index = FPDFDest_GetPageIndex(engine_->doc(), destination); | 372 if (target) |
373 if (target) { | 373 target->page = FPDFDest_GetPageIndex(engine_->doc(), destination); |
374 target->page = page_index; | |
375 } | |
376 return DOCLINK_AREA; | 374 return DOCLINK_AREA; |
377 } | 375 } |
378 | 376 |
379 int PDFiumPage::GetLink(int char_index, PDFiumPage::LinkTarget* target) { | 377 int PDFiumPage::GetLink(int char_index, PDFiumPage::LinkTarget* target) { |
380 if (!available_) | 378 if (!available_) |
381 return -1; | 379 return -1; |
382 | 380 |
383 CalculateLinks(); | 381 CalculateLinks(); |
384 | 382 |
385 // Get the bounding box of the rect again, since it might have moved because | 383 // Get the bounding box of the rect again, since it might have moved because |
386 // of the tolerance above. | 384 // of the tolerance above. |
387 double left, right, bottom, top; | 385 double left, right, bottom, top; |
388 FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top); | 386 FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top); |
389 | 387 |
390 pp::Point origin( | 388 pp::Point origin( |
391 PageToScreen(pp::Point(), 1.0, left, top, right, bottom, 0).point()); | 389 PageToScreen(pp::Point(), 1.0, left, top, right, bottom, 0).point()); |
392 for (size_t i = 0; i < links_.size(); ++i) { | 390 for (size_t i = 0; i < links_.size(); ++i) { |
393 for (size_t j = 0; j < links_[i].rects.size(); ++j) { | 391 for (const auto& rect : links_[i].rects) { |
394 if (links_[i].rects[j].Contains(origin)) { | 392 if (rect.Contains(origin)) { |
395 if (target) | 393 if (target) |
396 target->url = links_[i].url; | 394 target->url = links_[i].url; |
397 return i; | 395 return i; |
398 } | 396 } |
399 } | 397 } |
400 } | 398 } |
401 return -1; | 399 return -1; |
402 } | 400 } |
403 | 401 |
404 std::vector<int> PDFiumPage::GetLinks(pp::Rect text_area, | 402 std::vector<int> PDFiumPage::GetLinks(pp::Rect text_area, |
405 std::vector<LinkTarget>* targets) { | 403 std::vector<LinkTarget>* targets) { |
| 404 std::vector<int> links; |
406 if (!available_) | 405 if (!available_) |
407 return std::vector<int>(); | 406 return links; |
408 | 407 |
409 CalculateLinks(); | 408 CalculateLinks(); |
410 | 409 |
411 std::vector<int> links; | |
412 | |
413 for (size_t i = 0; i < links_.size(); ++i) { | 410 for (size_t i = 0; i < links_.size(); ++i) { |
414 for (size_t j = 0; j < links_[i].rects.size(); ++j) { | 411 for (const auto& rect : links_[i].rects) { |
415 if (links_[i].rects[j].Intersects(text_area)) { | 412 if (rect.Intersects(text_area)) { |
416 if (targets) { | 413 if (targets) { |
417 LinkTarget target; | 414 LinkTarget target; |
418 target.url = links_[i].url; | 415 target.url = links_[i].url; |
419 targets->push_back(target); | 416 targets->push_back(target); |
420 } | 417 } |
421 links.push_back(i); | 418 links.push_back(i); |
422 } | 419 } |
423 } | 420 } |
424 } | 421 } |
425 return links; | 422 return links; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 } | 477 } |
481 FPDFLink_CloseWebLinks(links); | 478 FPDFLink_CloseWebLinks(links); |
482 } | 479 } |
483 | 480 |
484 pp::Rect PDFiumPage::PageToScreen(const pp::Point& offset, | 481 pp::Rect PDFiumPage::PageToScreen(const pp::Point& offset, |
485 double zoom, | 482 double zoom, |
486 double left, | 483 double left, |
487 double top, | 484 double top, |
488 double right, | 485 double right, |
489 double bottom, | 486 double bottom, |
490 int rotation) { | 487 int rotation) const { |
491 if (!available_) | 488 if (!available_) |
492 return pp::Rect(); | 489 return pp::Rect(); |
493 | 490 |
494 int new_left, new_top, new_right, new_bottom; | 491 int new_left, new_top, new_right, new_bottom; |
495 FPDF_PageToDevice( | 492 FPDF_PageToDevice( |
496 page_, | 493 page_, |
497 static_cast<int>((rect_.x() - offset.x()) * zoom), | 494 static_cast<int>((rect_.x() - offset.x()) * zoom), |
498 static_cast<int>((rect_.y() - offset.y()) * zoom), | 495 static_cast<int>((rect_.y() - offset.y()) * zoom), |
499 static_cast<int>(ceil(rect_.width() * zoom)), | 496 static_cast<int>(ceil(rect_.width() * zoom)), |
500 static_cast<int>(ceil(rect_.height() * zoom)), | 497 static_cast<int>(ceil(rect_.height() * zoom)), |
(...skipping 27 matching lines...) Expand all Loading... |
528 page_->loading_count_--; | 525 page_->loading_count_--; |
529 } | 526 } |
530 | 527 |
531 PDFiumPage::Link::Link() { | 528 PDFiumPage::Link::Link() { |
532 } | 529 } |
533 | 530 |
534 PDFiumPage::Link::~Link() { | 531 PDFiumPage::Link::~Link() { |
535 } | 532 } |
536 | 533 |
537 } // namespace chrome_pdf | 534 } // namespace chrome_pdf |
OLD | NEW |