Chromium Code Reviews| Index: pdf/pdfium/pdfium_page.cc |
| diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc |
| index af64660a2a8513cc98afc6d42e98fc4f9adf1d9c..c98ac7bfe29a07b0f0f2b8215b14fb70b868433e 100644 |
| --- a/pdf/pdfium/pdfium_page.cc |
| +++ b/pdf/pdfium/pdfium_page.cc |
| @@ -17,10 +17,15 @@ |
| #include "base/values.h" |
| #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h" |
| #include "pdf/pdfium/pdfium_engine.h" |
| +#include "printing/units.h" |
| // Used when doing hit detection. |
| #define kTolerance 20.0 |
| +using printing::ConvertUnitDouble; |
| +using printing::kPointsPerInch; |
| +using printing::kPixelsPerInch; |
| + |
| namespace { |
| // Dictionary Value key names for returning the accessible page content as JSON. |
| @@ -60,6 +65,40 @@ pp::Rect PageRectToGViewRect(FPDF_PAGE page, const pp::Rect& input) { |
| return output_rect; |
| } |
| +pp::FloatRect FloatPageRectToPixelRect( |
| + FPDF_PAGE page, const pp::FloatRect& input) { |
| + int output_width = FPDF_GetPageWidth(page); |
| + int output_height = FPDF_GetPageHeight(page); |
| + |
| + int min_x; |
| + int min_y; |
| + int max_x; |
| + int max_y; |
| + FPDF_PageToDevice(page, 0, 0, output_width, output_height, 0, |
| + input.x(), input.y(), &min_x, &min_y); |
| + FPDF_PageToDevice(page, 0, 0, output_width, output_height, 0, |
| + input.right(), input.bottom(), &max_x, &max_y); |
| + |
| + if (max_x < min_x) |
| + std::swap(min_x, max_x); |
| + if (max_y < min_y) |
| + std::swap(min_y, max_y); |
| + |
| + pp::FloatRect output_rect( |
| + ConvertUnitDouble(min_x, kPointsPerInch, kPixelsPerInch), |
| + ConvertUnitDouble(min_y, kPointsPerInch, kPixelsPerInch), |
| + ConvertUnitDouble(max_x - min_x, kPointsPerInch, kPixelsPerInch), |
| + ConvertUnitDouble(max_y - min_y, kPointsPerInch, kPixelsPerInch)); |
| + /* |
| + output_rect.Intersect(pp::FloatRect( |
| + 0, |
| + 0, |
| + ConvertUnitDouble(output_width, kPointsPerInch, kPixelsPerInch), |
| + ConvertUnitDouble(output_height, kPointsPerInch, kPixelsPerInch))); |
| + */ |
| + return output_rect; |
| +} |
| + |
| pp::Rect GetCharRectInGViewCoords(FPDF_PAGE page, FPDF_TEXTPAGE text_page, |
| int index) { |
| double left, right, bottom, top; |
| @@ -72,6 +111,18 @@ pp::Rect GetCharRectInGViewCoords(FPDF_PAGE page, FPDF_TEXTPAGE text_page, |
| return PageRectToGViewRect(page, page_coords); |
| } |
| +pp::FloatRect GetFloatCharRectInPixels( |
| + FPDF_PAGE page, FPDF_TEXTPAGE text_page, int index) { |
| + double left, right, bottom, top; |
| + FPDFText_GetCharBox(text_page, index, &left, &right, &bottom, &top); |
| + if (right < left) |
| + std::swap(left, right); |
| + if (bottom < top) |
| + std::swap(top, bottom); |
| + pp::FloatRect page_coords(left, top, right - left, bottom - top); |
| + return FloatPageRectToPixelRect(page, page_coords); |
| +} |
| + |
| // This is the character PDFium inserts where a word is broken across lines. |
| const unsigned int kSoftHyphen = 0x02; |
| @@ -98,6 +149,11 @@ bool OverlapsOnYAxis(const pp::Rect &a, const pp::Rect& b) { |
| a.bottom() < b.y() || b.bottom() < a.y()); |
| } |
| +bool OverlapsOnYAxis(const pp::FloatRect &a, const pp::FloatRect& b) { |
| + return !(a.IsEmpty() || b.IsEmpty() || |
| + a.bottom() < b.y() || b.bottom() < a.y()); |
| +} |
| + |
| bool IsEol(unsigned int character) { |
| const unsigned int* first = kUnicodeNewlines; |
| const unsigned int* last = kUnicodeNewlines + arraysize(kUnicodeNewlines); |
| @@ -299,6 +355,57 @@ base::Value* PDFiumPage::GetAccessibleContentAsValue(int rotation) { |
| return node; |
| } |
| +bool PDFiumPage::GetTextRunInfo( |
|
Lei Zhang
2016/05/09 23:58:49
Can this be void since it always returns true? The
dmazzoni
2016/05/10 22:09:18
Done.
|
| + int start_char_index, |
| + uint32_t* out_len, |
| + double* out_font_size, |
| + pp::FloatRect* out_bounds) { |
| + FPDF_PAGE page = GetPage(); |
| + FPDF_TEXTPAGE text_page = GetTextPage(); |
| + int chars_count = FPDFText_CountChars(text_page); |
| + int char_index = start_char_index; |
| + while (char_index < chars_count && |
| + base::IsUnicodeWhitespace( |
| + FPDFText_GetUnicode(text_page, char_index))) { |
| + char_index++; |
| + } |
| + int text_run_font_size = FPDFText_GetFontSize(text_page, char_index); |
| + pp::FloatRect text_run_bounds = GetFloatCharRectInPixels( |
| + page, text_page, char_index); |
| + char_index++; |
| + while (char_index < chars_count) { |
| + unsigned int character = FPDFText_GetUnicode(text_page, char_index); |
| + |
| + if (!base::IsUnicodeWhitespace(character)) { |
| + // TODO(dmazzoni): this assumes horizontal text. |
| + // https://crbug.com/580311 |
| + pp::FloatRect char_rect = GetFloatCharRectInPixels( |
| + page, text_page, char_index); |
| + if (!char_rect.IsEmpty() && !OverlapsOnYAxis(text_run_bounds, char_rect)) |
| + break; |
| + |
| + int font_size = FPDFText_GetFontSize(text_page, char_index); |
| + if (font_size != text_run_font_size) |
| + break; |
| + |
| + text_run_bounds = text_run_bounds.Union(char_rect); |
| + } |
| + |
| + char_index++; |
| + } |
| + |
| + *out_len = char_index - start_char_index; |
| + *out_font_size = text_run_font_size; |
| + *out_bounds = text_run_bounds; |
| + return true; |
| +} |
| + |
| +double PDFiumPage::GetCharWidth(int char_index) { |
| + FPDF_PAGE page = GetPage(); |
| + FPDF_TEXTPAGE text_page = GetTextPage(); |
| + return GetFloatCharRectInPixels(page, text_page, char_index).width(); |
| +} |
| + |
| PDFiumPage::Area PDFiumPage::GetCharIndex(const pp::Point& point, |
| int rotation, |
| int* char_index, |