| 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 |