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

Side by Side Diff: pdf/pdfium/pdfium_page.cc

Issue 2954813002: Refactor PDFiumPage::GetLinkTarget() into smaller methods. (Closed)
Patch Set: Created 3 years, 5 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 | « pdf/pdfium/pdfium_page.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 10 #include <algorithm>
11 #include <memory> 11 #include <memory>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/numerics/safe_math.h" 15 #include "base/numerics/safe_math.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h" 19 #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h"
20 #include "pdf/pdfium/pdfium_engine.h" 20 #include "pdf/pdfium/pdfium_engine.h"
21 #include "printing/units.h" 21 #include "printing/units.h"
22 22
23 // Used when doing hit detection.
24 #define kTolerance 20.0
25
26 using printing::ConvertUnitDouble; 23 using printing::ConvertUnitDouble;
27 using printing::kPointsPerInch; 24 using printing::kPointsPerInch;
28 using printing::kPixelsPerInch; 25 using printing::kPixelsPerInch;
29 26
30 namespace { 27 namespace {
31 28
32 pp::FloatRect FloatPageRectToPixelRect(FPDF_PAGE page, 29 pp::FloatRect FloatPageRectToPixelRect(FPDF_PAGE page,
33 const pp::FloatRect& input) { 30 const pp::FloatRect& input) {
34 int output_width = FPDF_GetPageWidth(page); 31 int output_width = FPDF_GetPageWidth(page);
35 int output_height = FPDF_GetPageHeight(page); 32 int output_height = FPDF_GetPageHeight(page);
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 int* form_type, 237 int* form_type,
241 LinkTarget* target) { 238 LinkTarget* target) {
242 if (!available_) 239 if (!available_)
243 return NONSELECTABLE_AREA; 240 return NONSELECTABLE_AREA;
244 pp::Point point2 = point - rect_.point(); 241 pp::Point point2 = point - rect_.point();
245 double new_x; 242 double new_x;
246 double new_y; 243 double new_y;
247 FPDF_DeviceToPage(GetPage(), 0, 0, rect_.width(), rect_.height(), rotation, 244 FPDF_DeviceToPage(GetPage(), 0, 0, rect_.width(), rect_.height(), rotation,
248 point2.x(), point2.y(), &new_x, &new_y); 245 point2.x(), point2.y(), &new_x, &new_y);
249 246
247 // hit detection tolerance, in points.
248 constexpr double kTolerance = 20.0;
250 int rv = FPDFText_GetCharIndexAtPos(GetTextPage(), new_x, new_y, kTolerance, 249 int rv = FPDFText_GetCharIndexAtPos(GetTextPage(), new_x, new_y, kTolerance,
251 kTolerance); 250 kTolerance);
252 *char_index = rv; 251 *char_index = rv;
253 252
254 FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), new_x, new_y); 253 FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), new_x, new_y);
255 int control = 254 int control =
256 FPDFPage_HasFormFieldAtPoint(engine_->form(), GetPage(), new_x, new_y); 255 FPDFPage_HasFormFieldAtPoint(engine_->form(), GetPage(), new_x, new_y);
257 256
258 // If there is a control and link at the same point, figure out their z-order 257 // If there is a control and link at the same point, figure out their z-order
259 // to determine which is on top. 258 // to determine which is on top.
260 if (link && control > FPDF_FORMFIELD_UNKNOWN) { 259 if (link && control > FPDF_FORMFIELD_UNKNOWN) {
261 int control_z_order = FPDFPage_FormFieldZOrderAtPoint( 260 int control_z_order = FPDFPage_FormFieldZOrderAtPoint(
262 engine_->form(), GetPage(), new_x, new_y); 261 engine_->form(), GetPage(), new_x, new_y);
263 int link_z_order = FPDFLink_GetLinkZOrderAtPoint(GetPage(), new_x, new_y); 262 int link_z_order = FPDFLink_GetLinkZOrderAtPoint(GetPage(), new_x, new_y);
264 DCHECK_NE(control_z_order, link_z_order); 263 DCHECK_NE(control_z_order, link_z_order);
265 if (control_z_order > link_z_order) { 264 if (control_z_order > link_z_order) {
266 *form_type = control; 265 *form_type = control;
267 return FormTypeToArea(*form_type); 266 return FormTypeToArea(*form_type);
268 } 267 }
269 268
270 // We don't handle all possible link types of the PDF. For example, 269 // We don't handle all possible link types of the PDF. For example,
271 // launch actions, cross-document links, etc. 270 // launch actions, cross-document links, etc.
272 // In that case, GetLinkTarget() will return NONSELECTABLE_AREA 271 // In that case, GetLinkTarget() will return NONSELECTABLE_AREA
273 // and we should proceed with area detection. 272 // and we should proceed with area detection.
274 PDFiumPage::Area area = GetLinkTarget(link, target); 273 Area area = GetLinkTarget(link, target);
275 if (area != PDFiumPage::NONSELECTABLE_AREA) 274 if (area != NONSELECTABLE_AREA)
276 return area; 275 return area;
277 } else if (link) { 276 } else if (link) {
278 // We don't handle all possible link types of the PDF. For example, 277 // We don't handle all possible link types of the PDF. For example,
279 // launch actions, cross-document links, etc. 278 // launch actions, cross-document links, etc.
280 // See identical block above. 279 // See identical block above.
281 PDFiumPage::Area area = GetLinkTarget(link, target); 280 Area area = GetLinkTarget(link, target);
282 if (area != PDFiumPage::NONSELECTABLE_AREA) 281 if (area != NONSELECTABLE_AREA)
283 return area; 282 return area;
284 } else if (control > FPDF_FORMFIELD_UNKNOWN) { 283 } else if (control > FPDF_FORMFIELD_UNKNOWN) {
285 *form_type = control; 284 *form_type = control;
286 return FormTypeToArea(*form_type); 285 return FormTypeToArea(*form_type);
287 } 286 }
288 287
289 if (rv < 0) 288 if (rv < 0)
290 return NONSELECTABLE_AREA; 289 return NONSELECTABLE_AREA;
291 290
292 return GetLink(*char_index, target) != -1 ? WEBLINK_AREA : TEXT_AREA; 291 return GetLink(*char_index, target) != -1 ? WEBLINK_AREA : TEXT_AREA;
293 } 292 }
294 293
295 // static 294 // static
296 PDFiumPage::Area PDFiumPage::FormTypeToArea(int form_type) { 295 PDFiumPage::Area PDFiumPage::FormTypeToArea(int form_type) {
297 switch (form_type) { 296 switch (form_type) {
298 case FPDF_FORMFIELD_COMBOBOX: 297 case FPDF_FORMFIELD_COMBOBOX:
299 case FPDF_FORMFIELD_TEXTFIELD: 298 case FPDF_FORMFIELD_TEXTFIELD:
300 return PDFiumPage::FORM_TEXT_AREA; 299 return FORM_TEXT_AREA;
301 default: 300 default:
302 return PDFiumPage::NONSELECTABLE_AREA; 301 return NONSELECTABLE_AREA;
303 } 302 }
304 } 303 }
305 304
306 base::char16 PDFiumPage::GetCharAtIndex(int index) { 305 base::char16 PDFiumPage::GetCharAtIndex(int index) {
307 if (!available_) 306 if (!available_)
308 return L'\0'; 307 return L'\0';
309 return static_cast<base::char16>(FPDFText_GetUnicode(GetTextPage(), index)); 308 return static_cast<base::char16>(FPDFText_GetUnicode(GetTextPage(), index));
310 } 309 }
311 310
312 int PDFiumPage::GetCharCount() { 311 int PDFiumPage::GetCharCount() {
313 if (!available_) 312 if (!available_)
314 return 0; 313 return 0;
315 return FPDFText_CountChars(GetTextPage()); 314 return FPDFText_CountChars(GetTextPage());
316 } 315 }
317 316
318 PDFiumPage::Area PDFiumPage::GetLinkTarget( 317 PDFiumPage::Area PDFiumPage::GetLinkTarget(FPDF_LINK link,
319 FPDF_LINK link, 318 LinkTarget* target) const {
320 PDFiumPage::LinkTarget* target) const {
321 FPDF_DEST dest = FPDFLink_GetDest(engine_->doc(), link); 319 FPDF_DEST dest = FPDFLink_GetDest(engine_->doc(), link);
322 if (dest) 320 if (dest)
323 return GetDestinationTarget(dest, target); 321 return GetDestinationTarget(dest, target);
324 322
325 FPDF_ACTION action = FPDFLink_GetAction(link); 323 FPDF_ACTION action = FPDFLink_GetAction(link);
326 if (action) { 324 if (!action)
327 // TODO(gene): We don't support PDFACTION_REMOTEGOTO and 325 return NONSELECTABLE_AREA;
328 // PDFACTION_LAUNCH at the moment. 326
329 switch (FPDFAction_GetType(action)) { 327 switch (FPDFAction_GetType(action)) {
330 case PDFACTION_GOTO: { 328 case PDFACTION_GOTO: {
331 FPDF_DEST dest = FPDFAction_GetDest(engine_->doc(), action); 329 FPDF_DEST dest = FPDFAction_GetDest(engine_->doc(), action);
332 if (dest) 330 if (dest)
333 return GetDestinationTarget(dest, target); 331 return GetDestinationTarget(dest, target);
334 // TODO(gene): We don't fully support all types of the in-document 332 // TODO(thestig): We don't fully support all types of the in-document
335 // links. Need to implement that. There is a bug to track that: 333 // links. Need to implement that. There is a bug to track that:
336 // http://code.google.com/p/chromium/issues/detail?id=55776 334 // https://crbug.com/55776
337 break; 335 return NONSELECTABLE_AREA;
338 }
339 case PDFACTION_URI: {
340 if (target) {
341 size_t buffer_size =
342 FPDFAction_GetURIPath(engine_->doc(), action, nullptr, 0);
343 if (buffer_size > 0) {
344 PDFiumAPIStringBufferAdapter<std::string> api_string_adapter(
345 &target->url, buffer_size, true);
346 void* data = api_string_adapter.GetData();
347 size_t bytes_written = FPDFAction_GetURIPath(engine_->doc(), action,
348 data, buffer_size);
349 api_string_adapter.Close(bytes_written);
350 }
351 }
352 return WEBLINK_AREA;
353 }
354 } 336 }
337 case PDFACTION_URI:
338 return GetURITarget(action, target);
339 // TODO(thestig): Support remaining types for https://crbug.com/55776
340 case PDFACTION_LAUNCH:
341 case PDFACTION_REMOTEGOTO:
342 default:
343 return NONSELECTABLE_AREA;
355 } 344 }
356
357 return NONSELECTABLE_AREA;
358 } 345 }
359 346
360 PDFiumPage::Area PDFiumPage::GetDestinationTarget( 347 PDFiumPage::Area PDFiumPage::GetDestinationTarget(FPDF_DEST destination,
361 FPDF_DEST destination, 348 LinkTarget* target) const {
362 PDFiumPage::LinkTarget* target) const {
363 if (target) 349 if (target)
364 target->page = FPDFDest_GetPageIndex(engine_->doc(), destination); 350 target->page = FPDFDest_GetPageIndex(engine_->doc(), destination);
365 return DOCLINK_AREA; 351 return DOCLINK_AREA;
366 } 352 }
367 353
368 int PDFiumPage::GetLink(int char_index, PDFiumPage::LinkTarget* target) { 354 PDFiumPage::Area PDFiumPage::GetURITarget(FPDF_ACTION uri_action,
355 LinkTarget* target) const {
356 if (target) {
dsinclair 2017/06/26 19:44:38 if (!target) return WEBLINK_AREA;
Lei Zhang 2017/06/26 20:57:59 I wrote it this way because: - Early returns ends
357 size_t buffer_size =
358 FPDFAction_GetURIPath(engine_->doc(), uri_action, nullptr, 0);
359 if (buffer_size > 0) {
dsinclair 2017/06/26 19:44:39 ditto early exit?
360 PDFiumAPIStringBufferAdapter<std::string> api_string_adapter(
361 &target->url, buffer_size, true);
362 void* data = api_string_adapter.GetData();
363 size_t bytes_written =
364 FPDFAction_GetURIPath(engine_->doc(), uri_action, data, buffer_size);
365 api_string_adapter.Close(bytes_written);
366 }
367 }
368 return WEBLINK_AREA;
369 }
370
371 int PDFiumPage::GetLink(int char_index, LinkTarget* target) {
369 if (!available_) 372 if (!available_)
370 return -1; 373 return -1;
371 374
372 CalculateLinks(); 375 CalculateLinks();
373 376
374 // Get the bounding box of the rect again, since it might have moved because 377 // Get the bounding box of the rect again, since it might have moved because
375 // of the tolerance above. 378 // of the tolerance above.
376 double left, right, bottom, top; 379 double left, right, bottom, top;
377 FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top); 380 FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top);
378 381
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 page_->loading_count_--; 536 page_->loading_count_--;
534 } 537 }
535 538
536 PDFiumPage::Link::Link() = default; 539 PDFiumPage::Link::Link() = default;
537 540
538 PDFiumPage::Link::Link(const Link& that) = default; 541 PDFiumPage::Link::Link(const Link& that) = default;
539 542
540 PDFiumPage::Link::~Link() = default; 543 PDFiumPage::Link::~Link() = default;
541 544
542 } // namespace chrome_pdf 545 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « pdf/pdfium/pdfium_page.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698