pdfium_engine.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "pdf/pdfium/pdfium_engine.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <math.h>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/json/json_writer.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/stl_util.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_piece.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_util.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/values.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "pdf/draw_utils.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "pdf/pdfium/pdfium_mem_buffer_file_read.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "pdf/pdfium/pdfium_mem_buffer_file_write.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/c/pp_input_event.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/c/ppb_core.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/c/private/ppb_pdf.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/dev/memory_dev.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/input_event.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/instance.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/module.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/private/pdf.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/trusted/browser_font_trusted.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/url_response_info.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/var.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdf_ext.h"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdf_flatten.h"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdf_searchex.h"
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdf_sysfontinfo.h"
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdf_transformpage.h"
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdfedit.h"
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdfoom.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdfppo.h"
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/fpdfsave.h"
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/pdfwindow/PDFWindow.h"
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/pdfium/fpdfsdk/include/pdfwindow/PWL_FontMap.h"
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chrome_pdf {
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPageShadowTop    3
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPageShadowBottom 7
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPageShadowLeft   5
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPageShadowRight  5
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPageSeparatorThickness 4
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kHighlightColorR 153
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kHighlightColorG 193
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kHighlightColorB 218
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPendingPageColorR 238
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPendingPageColorG 238
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPendingPageColorB 238
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPendingPageColorA 255
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kFormHighlightColor 0xFFE4DD
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kFormHighlightAlpha 100
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kMaxPasswordTries 3
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See Table 3.20 in
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPDFPermissionPrintLowQualityMask  1 << 2
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPDFPermissionPrintHighQualityMask 1 << 11
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPDFPermissionCopyMask             1 << 4
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kPDFPermissionCopyAccessibleMask   1 << 9
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kLoadingTextVerticalOffset 50
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The maximum amount of time we'll spend doing a paint before we give back
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// control of the thread.
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kMaxProgressivePaintTimeMs 50
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The maximum amount of time we'll spend doing the first paint. This is less
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// than the above to keep things smooth if the user is scrolling quickly. We
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// try painting a little because with accelerated compositing, we get flushes
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// only every 16 ms. If we were to wait until the next flush to paint the rest
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// of the pdf, we would never get to draw the pdf and would only draw the
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// scrollbars. This value is picked to give enough time for gpu related code to
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// do its thing and still fit within the timelimit for 60Hz. For the
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// non-composited case, this doesn't make things worse since we're still
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// painting the scrollbars > 60 Hz.
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kMaxInitialProgressivePaintTimeMs 10
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copied from printing/units.cc because we don't want to depend on printing
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// since it brings in libpng which causes duplicate symbols with PDFium.
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kPointsPerInch = 72;
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kPixelsPerInch = 96;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct ClipBox {
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float left;
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float right;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float top;
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float bottom;
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ConvertUnit(int value, int old_unit, int new_unit) {
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // With integer arithmetic, to divide a value with correct rounding, you need
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // to add half of the divisor value to the dividend value. You need to do the
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // reverse with negative number.
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (value >= 0) {
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return ((value * new_unit) + (old_unit / 2)) / old_unit;
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return ((value * new_unit) - (old_unit / 2)) / old_unit;
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::vector<uint32_t> GetPageNumbersFromPrintPageNumberRange(
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintPageNumberRange_Dev* page_ranges,
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32_t page_range_count) {
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<uint32_t> page_numbers;
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (uint32_t index = 0; index < page_range_count; ++index) {
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (uint32_t page_number = page_ranges[index].first_page_number;
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         page_number <= page_ranges[index].last_page_number; ++page_number) {
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_numbers.push_back(page_number);
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return page_numbers;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_LINUX)
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PP_Instance g_last_instance_id;
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct PDFFontSubstitution {
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* pdf_name;
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* face;
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool bold;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool italic;
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This list is for CPWL_FontMap::GetDefaultFontByCharset().
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// We pretend to have these font natively and let the browser (or underlying
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// fontconfig) to pick the proper font on the system.
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_AddInstalledFont(mapper, "Arial", FXFONT_DEFAULT_CHARSET);
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int i = 0;
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (CPWL_FontMap::defaultTTFMap[i].charset != -1) {
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_AddInstalledFont(mapper,
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          CPWL_FontMap::defaultTTFMap[i].fontname,
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          CPWL_FontMap::defaultTTFMap[i].charset);
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++i;
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const PDFFontSubstitution PDFFontSubstitutions[] = {
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Courier", "Courier New", false, false},
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Courier-Bold", "Courier New", true, false},
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Courier-BoldOblique", "Courier New", true, true},
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Courier-Oblique", "Courier New", false, true},
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Helvetica", "Arial", false, false},
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Helvetica-Bold", "Arial", true, false},
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Helvetica-BoldOblique", "Arial", true, true},
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Helvetica-Oblique", "Arial", false, true},
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Times-Roman", "Times New Roman", false, false},
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Times-Bold", "Times New Roman", true, false},
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Times-BoldItalic", "Times New Roman", true, true},
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"Times-Italic", "Times New Roman", false, true},
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // MS P?(Mincho|Gothic) are the most notable fonts in Japanese PDF files
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // without embedding the glyphs. Sometimes the font names are encoded
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // in Japanese Windows's locale (CP932/Shift_JIS) without space.
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Most Linux systems don't have the exact font, but for outsourcing
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // fontconfig to find substitutable font in the system, we pass ASCII
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // font names to it.
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"MS-PGothic", "MS PGothic", false, false},
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"MS-Gothic", "MS Gothic", false, false},
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"MS-PMincho", "MS PMincho", false, false},
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"MS-Mincho", "MS Mincho", false, false},
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // MS PGothic in Shift_JIS encoding.
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"\x82\x6C\x82\x72\x82\x6F\x83\x53\x83\x56\x83\x62\x83\x4E",
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     "MS PGothic", false, false},
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // MS Gothic in Shift_JIS encoding.
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"\x82\x6C\x82\x72\x83\x53\x83\x56\x83\x62\x83\x4E",
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     "MS Gothic", false, false},
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // MS PMincho in Shift_JIS encoding.
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"\x82\x6C\x82\x72\x82\x6F\x96\xBE\x92\xA9",
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     "MS PMincho", false, false},
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // MS Mincho in Shift_JIS encoding.
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    {"\x82\x6C\x82\x72\x96\xBE\x92\xA9",
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     "MS Mincho", false, false},
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic,
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              int charset, int pitch_family, const char* face, int* exact) {
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::BrowserFontDescription description;
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Pretend the system does not have the Symbol font to force a fallback to
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the built in Symbol font in CFX_FontMapper::FindSubstFont().
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (strcmp(face, "Symbol") == 0)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (pitch_family & FXFONT_FF_FIXEDPITCH) {
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE);
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (pitch_family & FXFONT_FF_ROMAN) {
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_SERIF);
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Map from the standard PDF fonts to TrueType font names.
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t i;
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (i = 0; i < arraysize(PDFFontSubstitutions); ++i) {
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (strcmp(face, PDFFontSubstitutions[i].pdf_name) == 0) {
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      description.set_face(PDFFontSubstitutions[i].face);
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (PDFFontSubstitutions[i].bold)
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        description.set_weight(PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD);
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (PDFFontSubstitutions[i].italic)
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        description.set_italic(true);
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (i == arraysize(PDFFontSubstitutions)) {
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(kochi): Pass the face in UTF-8. If face is not encoded in UTF-8,
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // convert to UTF-8 before passing.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    description.set_face(face);
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!pp::PDF::IsAvailable()) {
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PP_Resource font_resource = pp::PDF::GetFontFileWithFallback(
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pp::InstanceHandle(g_last_instance_id),
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &description.pp_font_description(),
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<PP_PrivateFontCharset>(charset));
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  long res_id = font_resource;
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return reinterpret_cast<void*>(res_id);
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)unsigned long GetFontData(struct _FPDF_SYSFONTINFO*, void* font_id,
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          unsigned int table, unsigned char* buffer,
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          unsigned long buf_size) {
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!pp::PDF::IsAvailable()) {
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0;
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32_t size = buf_size;
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  long res_id = reinterpret_cast<long>(font_id);
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!pp::PDF::GetFontTableForPrivateFontFile(res_id, table, buffer, &size))
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0;
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return size;
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DeleteFont(struct _FPDF_SYSFONTINFO*, void* font_id) {
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  long res_id = reinterpret_cast<long>(font_id);
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Module::Get()->core()->ReleaseResource(res_id);
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_SYSFONTINFO g_font_info = {
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  1,
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  0,
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EnumFonts,
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MapFont,
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  0,
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetFontData,
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  0,
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  0,
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DeleteFont
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(OS_LINUX)
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OOM_Handler(_OOM_INFO*) {
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Kill the process.  This is important for security, since the code doesn't
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // NULL-check many memory allocations.  If a malloc fails, returns NULL, and
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the buffer is then used, it provides a handy mapping of memory starting at
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // address 0 for an attacker to utilize.
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  abort();
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)OOM_INFO g_oom_info = {
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  1,
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  OOM_Handler
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine* g_engine_for_unsupported;
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Unsupported_Handler(UNSUPPORT_INFO*, int type) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!g_engine_for_unsupported) {
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_engine_for_unsupported->UnsupportedFeature(type);
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)UNSUPPORT_INFO g_unsuppored_info = {
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  1,
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Unsupported_Handler
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Set the destination page size and content area in points based on source
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// page rotation and orientation.
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |rotated| True if source page is rotated 90 degree or 270 degree.
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |is_src_page_landscape| is true if the source page orientation is landscape.
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page_size| has the actual destination page size in points.
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |content_rect| has the actual destination page printable area values in
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// points.
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SetPageSizeAndContentRect(bool rotated,
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               bool is_src_page_landscape,
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               pp::Size* page_size,
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               pp::Rect* content_rect) {
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_dst_page_landscape = page_size->width() > page_size->height();
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool page_orientation_mismatched = is_src_page_landscape !=
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     is_dst_page_landscape;
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool rotate_dst_page = rotated ^ page_orientation_mismatched;
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (rotate_dst_page) {
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_size->SetSize(page_size->height(), page_size->width());
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content_rect->SetRect(content_rect->y(), content_rect->x(),
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          content_rect->height(), content_rect->width());
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Calculate the scale factor between |content_rect| and a page of size
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |src_width| x |src_height|.
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |scale_to_fit| is true, if we need to calculate the scale factor.
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |content_rect| specifies the printable area of the destination page, with
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// origin at left-bottom. Values are in points.
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |src_width| specifies the source page width in points.
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |src_height| specifies the source page height in points.
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |rotated| True if source page is rotated 90 degree or 270 degree.
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)double CalculateScaleFactor(bool scale_to_fit,
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            const pp::Rect& content_rect,
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            double src_width, double src_height, bool rotated) {
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!scale_to_fit || src_width == 0 || src_height == 0)
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 1.0;
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double actual_source_page_width = rotated ? src_height : src_width;
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double actual_source_page_height = rotated ? src_width : src_height;
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double ratio_x = static_cast<double>(content_rect.width()) /
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   actual_source_page_width;
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double ratio_y = static_cast<double>(content_rect.height()) /
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   actual_source_page_height;
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return std::min(ratio_x, ratio_y);
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Compute source clip box boundaries based on the crop box / media box of
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// source page and scale factor.
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page| Handle to the source page. Returned by FPDF_LoadPage function.
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |scale_factor| specifies the scale factor that should be applied to source
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// clip box boundaries.
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |rotated| True if source page is rotated 90 degree or 270 degree.
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |clip_box| out param to hold the computed source clip box values.
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CalculateClipBoxBoundary(FPDF_PAGE page, double scale_factor, bool rotated,
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              ClipBox* clip_box) {
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!FPDFPage_GetCropBox(page, &clip_box->left, &clip_box->bottom,
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           &clip_box->right, &clip_box->top)) {
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!FPDFPage_GetMediaBox(page, &clip_box->left, &clip_box->bottom,
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              &clip_box->right, &clip_box->top)) {
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Make the default size to be letter size (8.5" X 11"). We are just
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // following the PDFium way of handling these corner cases. PDFium always
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // consider US-Letter as the default page size.
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      float paper_width = 612;
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      float paper_height = 792;
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      clip_box->left = 0;
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      clip_box->bottom = 0;
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      clip_box->right = rotated ? paper_height : paper_width;
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      clip_box->top = rotated ? paper_width : paper_height;
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clip_box->left *= scale_factor;
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clip_box->right *= scale_factor;
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clip_box->bottom *= scale_factor;
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clip_box->top *= scale_factor;
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Calculate the clip box translation offset for a page that does need to be
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// scaled. All parameters are in points.
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |content_rect| specifies the printable area of the destination page, with
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// origin at left-bottom.
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |source_clip_box| specifies the source clip box positions, relative to
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// origin at left-bottom.
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |offset_x| and |offset_y| will contain the final translation offsets for the
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// source clip box, relative to origin at left-bottom.
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CalculateScaledClipBoxOffset(const pp::Rect& content_rect,
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const ClipBox& source_clip_box,
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  double* offset_x, double* offset_y) {
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const float clip_box_width = source_clip_box.right - source_clip_box.left;
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Center the intended clip region to real clip region.
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              source_clip_box.left;
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              source_clip_box.bottom;
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Calculate the clip box offset for a page that does not need to be scaled.
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// All parameters are in points.
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |content_rect| specifies the printable area of the destination page, with
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// origin at left-bottom.
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |rotation| specifies the source page rotation values which are N / 90
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// degrees.
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page_width| specifies the screen destination page width.
409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page_height| specifies the screen destination page height.
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |source_clip_box| specifies the source clip box positions, relative to origin
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// at left-bottom.
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |offset_x| and |offset_y| will contain the final translation offsets for the
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// source clip box, relative to origin at left-bottom.
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CalculateNonScaledClipBoxOffset(const pp::Rect& content_rect, int rotation,
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int page_width, int page_height,
416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     const ClipBox& source_clip_box,
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     double* offset_x, double* offset_y) {
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Align the intended clip region to left-top corner of real clip region.
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (rotation) {
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case 0:
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_x = -1 * source_clip_box.left;
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_y = page_height - source_clip_box.top;
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case 1:
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_x = 0;
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_y = -1 * source_clip_box.bottom;
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case 2:
429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_x = page_width - source_clip_box.right;
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_y = 0;
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case 3:
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_x = page_height - source_clip_box.right;
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *offset_y = page_width - source_clip_box.top;
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Do an in-place transformation of objects on |page|. Translate all objects on
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page| in |source_clip_box| by (|offset_x|, |offset_y|) and scale them by
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |scale_factor|.
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |page| Handle to the page. Returned by FPDF_LoadPage function.
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |source_clip_box| specifies the source clip box positions, relative to
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// origin at left-bottom.
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |scale_factor| specifies the scale factor that should be applied to page
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// objects.
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |offset_x| and |offset_y| specifies the translation offsets for the page
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// objects, relative to origin at left-bottom.
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void TransformPageObjects(FPDF_PAGE page, const ClipBox& source_clip_box,
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const double scale_factor, double offset_x,
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          double offset_y) {
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int obj_count = FPDFPage_CountObject(page);
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a new clip path.
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CLIPPATH clip_path = FPDF_CreateClipPath(
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      source_clip_box.left + offset_x, source_clip_box.bottom + offset_y,
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      source_clip_box.right + offset_x, source_clip_box.top + offset_y);
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGEOBJECT page_obj = FPDFPage_GetObject(page, obj_idx);
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPageObj_Transform(page_obj, scale_factor, 0, 0, scale_factor,
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          offset_x, offset_y);
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPageObj_TransformClipPath(page_obj, scale_factor, 0, 0, scale_factor,
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  offset_x, offset_y);
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor,
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           offset_x, offset_y);
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_GenerateContent(page);
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Add a extra clip path to the new pdf page here.
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_InsertClipPath(page, clip_path);
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Destroy the clip path.
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DestroyClipPath(clip_path);
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool InitializeSDK(void* data) {
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_InitLibrary(data);
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_LINUX)
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Font loading doesn't work in the renderer sandbox in Linux.
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_SetSystemFontInfo(&g_font_info);
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FSDK_SetOOMHandler(&g_oom_info);
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FSDK_SetUnSpObjProcessHandler(&g_unsuppored_info);
492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ShutdownSDK() {
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DestroyLibrary();
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFEngine* PDFEngine::Create(PDFEngine::Client* client) {
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new PDFiumEngine(client);
502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine::PDFiumEngine(PDFEngine::Client* client)
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : client_(client),
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_zoom_(1.0),
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_rotation_(0),
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      doc_loader_(this),
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      password_tries_remaining_(0),
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      doc_(NULL),
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_(NULL),
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      defer_page_unload_(false),
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selecting_(false),
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      next_page_to_search_(-1),
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_page_to_search_(-1),
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_character_index_to_search_(-1),
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_find_index_(-1),
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      permissions_(0),
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      fpdf_availability_(NULL),
520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      next_timer_id_(0),
521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_page_mouse_down_(-1),
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      first_visible_page_(-1),
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      most_visible_page_(-1),
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      called_do_document_action_(false),
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      render_grayscale_(false),
526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      progressive_paint_timeout_(0),
527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      getting_password_(false) {
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_factory_.Initialize(this);
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  password_factory_.Initialize(this);
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_access_.m_FileLen = 0;
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_access_.m_GetBlock = &GetBlock;
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_access_.m_Param = &doc_loader_;
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_availability_.version = 1;
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_availability_.IsDataAvail = &IsDataAvail;
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_availability_.loader = &doc_loader_;
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  download_hints_.version = 1;
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  download_hints_.AddSegment = &AddSegment;
541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  download_hints_.loader = &doc_loader_;
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Initialize FPDF_FORMFILLINFO member variables.  Deriving from this struct
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // allows the static callbacks to be able to cast the FPDF_FORMFILLINFO in
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // callbacks to ourself instead of maintaining a map of them to
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // PDFiumEngine.
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::version = 1;
548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::m_pJsPlatform = this;
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::Release = NULL;
550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_Invalidate = Form_Invalidate;
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_OutputSelectedRect = Form_OutputSelectedRect;
552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_SetCursor = Form_SetCursor;
553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_SetTimer = Form_SetTimer;
554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_KillTimer = Form_KillTimer;
555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_GetLocalTime = Form_GetLocalTime;
556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_OnChange = Form_OnChange;
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_GetPage = Form_GetPage;
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_GetCurrentPage = Form_GetCurrentPage;
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_GetRotation = Form_GetRotation;
560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_ExecuteNamedAction = Form_ExecuteNamedAction;
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_SetTextFieldFocus = Form_SetTextFieldFocus;
562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_DoURIAction = Form_DoURIAction;
563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FORMFILLINFO::FFI_DoGoToAction = Form_DoGoToAction;
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::version = 1;
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::app_alert = Form_Alert;
567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::app_beep = Form_Beep;
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::app_response = Form_Response;
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Doc_getFilePath = Form_GetFilePath;
570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Doc_mail = Form_Mail;
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Doc_print = Form_Print;
572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Doc_submitForm = Form_SubmitForm;
573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Doc_gotoPage = Form_GotoPage;
574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPDF_JSPLATFORM::Field_browse = Form_Browse;
575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IFSDK_PAUSE::version = 1;
577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IFSDK_PAUSE::user = NULL;
578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IFSDK_PAUSE::NeedToPauseNow = Pause_NeedToPauseNow;
579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine::~PDFiumEngine() {
582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  STLDeleteElements(&pages_);
583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_) {
584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (form_) {
585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_WC);
586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDFDOC_ExitFormFillEnviroument(form_);
587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(doc_);
589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (fpdf_availability_)
592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFAvail_Destroy(fpdf_availability_);
593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetBlock(void* param, unsigned long position,
596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           unsigned char* buffer, unsigned long size) {
597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DocumentLoader* loader = static_cast<DocumentLoader*>(param);
598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return loader->GetBlock(position, size, buffer);
599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::IsDataAvail(FX_FILEAVAIL* param,
602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               size_t offset, size_t size) {
603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine::FileAvail* file_avail =
604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<PDFiumEngine::FileAvail*>(param);
605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return file_avail->loader->IsDataAvailable(offset, size);
606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::AddSegment(FX_DOWNLOADHINTS* param,
609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              size_t offset, size_t size) {
610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine::DownloadHints* download_hints =
611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<PDFiumEngine::DownloadHints*>(param);
612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return download_hints->loader->RequestData(offset, size);
613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::New(const char* url) {
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  url_ = url;
617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  headers_ = std::string();
618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::New(const char* url,
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       const char* headers) {
623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  url_ = url;
624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!headers)
625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    headers_ = std::string();
626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    headers_ = headers;
628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PageOffsetUpdated(const pp::Point& page_offset) {
632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_offset_ = page_offset;
633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PluginSizeUpdated(const pp::Size& size) {
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CancelPaints();
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  plugin_size_ = size;
639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::ScrolledToXPosition(int position) {
643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CancelPaints();
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int old_x = position_.x();
646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  position_.set_x(position);
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->Scroll(pp::Point(old_x - position, 0));
649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::ScrolledToYPosition(int position) {
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CancelPaints();
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int old_y = position_.y();
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  position_.set_y(position);
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->Scroll(pp::Point(0, old_y - position));
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PrePaint() {
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < progressive_paints_.size(); ++i)
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    progressive_paints_[i].painted_ = false;
663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Paint(const pp::Rect& rect,
666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         pp::ImageData* image_data,
667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         std::vector<pp::Rect>* ready,
668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         std::vector<pp::Rect>* pending) {
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect leftover = rect;
670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < visible_pages_.size(); ++i) {
671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int index = visible_pages_[i];
672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect page_rect = pages_[index]->rect();
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Convert the current page's rectangle to screen rectangle.  We do this
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // instead of the reverse (converting the dirty rectangle from screen to
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // page coordinates) because then we'd have to convert back to screen
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // coordinates, and the rounding errors sometime leave pixels dirty or even
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // move the text up or down a pixel when zoomed.
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect page_rect_in_screen = GetPageScreenRect(index);
679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect dirty_in_screen = page_rect_in_screen.Intersect(leftover);
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (dirty_in_screen.IsEmpty())
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    leftover = leftover.Subtract(dirty_in_screen);
684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pages_[index]->available()) {
686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int progressive = GetProgressiveIndex(index);
687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (progressive != -1 &&
688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          progressive_paints_[progressive].rect != dirty_in_screen) {
689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // The PDFium code can only handle one progressive paint at a time, so
690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // queue this up. Previously we used to merge the rects when this
691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // happened, but it made scrolling up on complex PDFs very slow since
692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // there would be a damaged rect at the top (from scroll) and at the
693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // bottom (from toolbar).
694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pending->push_back(dirty_in_screen);
695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        continue;
696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (progressive == -1) {
699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        progressive = StartPaint(index, dirty_in_screen);
700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        progressive_paint_timeout_ = kMaxInitialProgressivePaintTimeMs;
701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        progressive_paint_timeout_ = kMaxProgressivePaintTimeMs;
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      progressive_paints_[progressive].painted_ = true;
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (ContinuePaint(progressive, image_data)) {
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FinishPaint(progressive, image_data);
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ready->push_back(dirty_in_screen);
709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pending->push_back(dirty_in_screen);
711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PaintUnavailablePage(index, dirty_in_screen, image_data);
714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ready->push_back(dirty_in_screen);
715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PostPaint() {
720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < progressive_paints_.size(); ++i) {
721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (progressive_paints_[i].painted_)
722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // This rectangle must have been merged with another one, that's why we
725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // weren't asked to paint it. Remove it or otherwise we'll never finish
726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // painting.
727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPage_Close(
728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[progressive_paints_[i].page_index]->GetPage());
729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_Destroy(progressive_paints_[i].bitmap);
730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    progressive_paints_.erase(progressive_paints_.begin() + i);
731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    --i;
732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::HandleDocumentLoad(const pp::URLLoader& loader) {
736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  password_tries_remaining_ = kMaxPasswordTries;
737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return doc_loader_.Init(loader, url_, headers_);
738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Instance* PDFiumEngine::GetPluginInstance() {
741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return client_->GetPluginInstance();
742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::URLLoader PDFiumEngine::CreateURLLoader() {
745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return client_->CreateURLLoader();
746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::AppendPage(PDFEngine* engine, int index) {
749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Unload and delete the blank page before appending.
750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pages_[index]->Unload();
751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pages_[index]->set_calculated_links(false);
752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size curr_page_size = GetPageSize(index);
753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_Delete(doc_, index);
754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_ImportPages(doc_,
755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   static_cast<PDFiumEngine*>(engine)->doc(),
756cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   "1",
757cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   index);
758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size new_page_size = GetPageSize(index);
759cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (curr_page_size != new_page_size)
760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadPageInfo(true);
761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->Invalidate(GetPageScreenRect(index));
762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Point PDFiumEngine::GetScrollPosition() {
765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return position_;
766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SetScrollPosition(const pp::Point& position) {
769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  position_ = position;
770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::IsProgressiveLoad() {
773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return doc_loader_.is_partial_document();
774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnPartialDocumentLoaded() {
777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_access_.m_FileLen = doc_loader_.document_size();
778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  fpdf_availability_ = FPDFAvail_Create(&file_availability_, &file_access_);
779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(fpdf_availability_);
780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Currently engine does not deal efficiently with some non-linearized files.
782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // See http://code.google.com/p/chromium/issues/detail?id=59400
783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // To improve user experience we download entire file for non-linearized PDF.
784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!FPDFAvail_IsLinearized(fpdf_availability_)) {
785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    doc_loader_.RequestData(0, doc_loader_.document_size());
786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoadDocument();
790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnPendingRequestComplete() {
793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_ || !form_) {
794cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadDocument();
795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // LoadDocument() will result in |pending_pages_| being reset so there's no
799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // need to run the code below in that case.
800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool update_pages = false;
801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<int> still_pending;
802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < pending_pages_.size(); ++i) {
803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (CheckPageAvailable(pending_pages_[i], &still_pending)) {
804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      update_pages = true;
805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (IsPageVisible(pending_pages_[i]))
806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        client_->Invalidate(GetPageScreenRect(pending_pages_[i]));
807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_pages_.swap(still_pending);
810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (update_pages)
811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadPageInfo(true);
812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnNewDataAvailable() {
815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->DocumentLoadProgress(doc_loader_.GetAvailableData(),
816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                doc_loader_.document_size());
817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnDocumentComplete() {
820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_ || !form_) {
821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_access_.m_FileLen = doc_loader_.document_size();
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadDocument();
823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool need_update = false;
827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < pages_.size(); ++i) {
828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pages_[i]->available())
829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_[i]->set_available(true);
832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We still need to call IsPageAvail() even if the whole document is
833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // already downloaded.
834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFAvail_IsPageAvail(fpdf_availability_, i, &download_hints_);
835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    need_update = true;
836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (IsPageVisible(i))
837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      client_->Invalidate(GetPageScreenRect(i));
838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (need_update)
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadPageInfo(true);
841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FinishLoadingDocument();
843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::FinishLoadingDocument() {
846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(doc_loader_.IsDocumentComplete() && doc_);
847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (called_do_document_action_)
848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  called_do_document_action_ = true;
850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // These can only be called now, as the JS might end up needing a page.
852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FORM_DoDocumentJSAction(form_);
853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FORM_DoDocumentOpenAction(form_);
854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (most_visible_page_ != -1) {
855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE new_page = pages_[most_visible_page_]->GetPage();
856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FORM_DoPageAAction(new_page, form_, FPDFPAGE_AACTION_OPEN);
857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_) // This can only happen if loading |doc_| fails.
860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentLoadComplete(pages_.size());
861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::UnsupportedFeature(int type) {
864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string feature;
865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (type) {
866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_XFAFORM:
867cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "XFA";
868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_PORTABLECOLLECTION:
870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Portfolios_Packages";
871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_ATTACHMENT:
873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_ATTACHMENT:
874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Attachment";
875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_SECURITY:
877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Rights_Management";
878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_SHAREDREVIEW:
880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Shared_Review";
881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT:
883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM:
884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_DOC_SHAREDFORM_EMAIL:
885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Shared_Form";
886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_3DANNOT:
888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "3D";
889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_MOVIE:
891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Movie";
892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_SOUND:
894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Sound";
895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_SCREEN_MEDIA:
897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA:
898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Screen";
899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case FPDF_UNSP_ANNOT_SIG:
901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      feature = "Digital_Signature";
902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->DocumentHasUnsupportedFeature(feature);
905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::ContinueFind(int32_t result) {
908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StartFind(current_find_text_.c_str(), !!result);
909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) {
912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!defer_page_unload_);
913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  defer_page_unload_ = true;
914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool rv = false;
915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (event.GetType()) {
916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnMouseDown(pp::MouseInputEvent(event));
918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
919cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEUP:
920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnMouseUp(pp::MouseInputEvent(event));
921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnMouseMove(pp::MouseInputEvent(event));
924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_KEYDOWN:
926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnKeyDown(pp::KeyboardInputEvent(event));
927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_KEYUP:
929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnKeyUp(pp::KeyboardInputEvent(event));
930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_CHAR:
932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rv = OnChar(pp::KeyboardInputEvent(event));
933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(defer_page_unload_);
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  defer_page_unload_ = false;
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < deferred_page_unloads_.size(); ++i)
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_[deferred_page_unloads_[i]]->Unload();
942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  deferred_page_unloads_.clear();
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv;
944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)uint32_t PDFiumEngine::QuerySupportedPrintOutputFormats() {
947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0;
949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return PP_PRINTOUTPUTFORMAT_PDF;
950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PrintBegin() {
953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_WP);
954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Resource PDFiumEngine::PrintPages(
957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintSettings_Dev& print_settings) {
959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))
960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PrintPagesAsPDF(page_ranges, page_range_count, print_settings);
961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PrintPagesAsRasterPDF(page_ranges, page_range_count, print_settings);
963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return pp::Resource();
964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Buffer_Dev PDFiumEngine::PrintPagesAsRasterPDF(
967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintSettings_Dev& print_settings) {
969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!page_range_count)
970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If document is not downloaded yet, disable printing.
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_ && !doc_loader_.IsDocumentComplete())
974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!output_doc)
978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SaveSelectedFormForPrint();
981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<PDFiumPage> pages_to_print;
983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // width and height of source PDF pages.
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::pair<double, double> > source_page_sizes;
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Collect pages to print and sizes of source pages.
986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<uint32_t> page_numbers =
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetPageNumbersFromPrintPageNumberRange(page_ranges, page_range_count);
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < page_numbers.size(); ++i) {
989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32_t page_number = page_numbers[i];
990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE pdf_page = FPDF_LoadPage(doc_, page_number);
991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double source_page_width = FPDF_GetPageWidth(pdf_page);
992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double source_page_height = FPDF_GetPageHeight(pdf_page);
993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    source_page_sizes.push_back(std::make_pair(source_page_width,
994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                               source_page_height));
995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int width_in_pixels = ConvertUnit(source_page_width,
997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      static_cast<int>(kPointsPerInch),
998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      print_settings.dpi);
999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int height_in_pixels = ConvertUnit(source_page_height,
1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       static_cast<int>(kPointsPerInch),
1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       print_settings.dpi);
1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rect(width_in_pixels, height_in_pixels);
1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_to_print.push_back(PDFiumPage(this, page_number, rect, true));
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_ClosePage(pdf_page);
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_LINUX)
1009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_last_instance_id = client_->GetPluginInstance()->pp_instance();
1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t i = 0;
1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (; i < pages_to_print.size(); ++i) {
1014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double source_page_width = source_page_sizes[i].first;
1015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double source_page_height = source_page_sizes[i].second;
1016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const pp::Size& bitmap_size(pages_to_print[i].rect().size());
1017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Use temp_doc to compress image by saving PDF to buffer.
1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_DOCUMENT temp_doc = FPDF_CreateNewDocument();
1020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!temp_doc)
1021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE output_page = FPDFPage_New(temp_doc, 0, source_page_width,
1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         source_page_height);
1025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::ImageData image = pp::ImageData(client_->GetPluginInstance(),
1027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        PP_IMAGEDATAFORMAT_BGRA_PREMUL,
1028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        bitmap_size,
1029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        false);
1030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1031cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(bitmap_size.width(),
1032cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             bitmap_size.height(),
1033cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             FPDFBitmap_BGRx,
1034cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             image.data(),
1035cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                             image.stride());
1036cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1037cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Clear the bitmap
1038cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(bitmap, 0, 0, bitmap_size.width(),
1039cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        bitmap_size.height(), 255, 255, 255, 255);
1040cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1041cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect page_rect = pages_to_print[i].rect();
1042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPageBitmap(bitmap, pages_to_print[i].GetPrintPage(),
1043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          page_rect.x(), page_rect.y(),
1044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          page_rect.width(), page_rect.height(),
1045cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          print_settings.orientation,
1046cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
1047cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1048cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double ratio_x = (static_cast<double>(bitmap_size.width()) *
1049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          kPointsPerInch) / print_settings.dpi;
1050cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double ratio_y = (static_cast<double>(bitmap_size.height()) *
1051cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         kPointsPerInch) / print_settings.dpi;
1052cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1053cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Add the bitmap to an image object and add the image object to the output
1054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // page.
1055cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGEOBJECT img_obj = FPDFPageObj_NewImgeObj(output_doc);
1056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFImageObj_SetBitmap(&output_page, 1, img_obj, bitmap);
1057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFImageObj_SetMatrix(img_obj, ratio_x, 0, 0, ratio_y, 0, 0);
1058cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPage_InsertObject(output_page, img_obj);
1059cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPage_GenerateContent(output_page);
1060cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_ClosePage(output_page);
1061cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1062cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_to_print[i].ClosePrintPage();
1063cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_Destroy(bitmap);
1064cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Buffer_Dev buffer = GetFlattenedPrintData(temp_doc);
1066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(temp_doc);
1067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PDFiumMemBufferFileRead file_read(buffer.data(), buffer.size());
1069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    temp_doc = FPDF_LoadCustomDocument(&file_read, NULL);
1070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!temp_doc)
1071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_BOOL imported = FPDF_ImportPages(output_doc, temp_doc, "1", i);
1074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(temp_doc);
1075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!imported)
1076cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1077cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Buffer_Dev buffer;
1080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (i == pages_to_print.size()) {
1081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CopyViewerPreferences(output_doc, doc_);
1082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FitContentsToPrintableAreaIfRequired(output_doc, print_settings);
1083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Now flatten all the output pages.
1084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    buffer = GetFlattenedPrintData(output_doc);
1085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CloseDocument(output_doc);
1087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return buffer;
1088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Buffer_Dev PDFiumEngine::GetFlattenedPrintData(const FPDF_DOCUMENT& doc) {
1091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_count = FPDF_GetPageCount(doc);
1092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool flatten_succeeded = true;
1093cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 0; i < page_count; ++i) {
1094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE page = FPDF_LoadPage(doc, i);
1095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(page);
1096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (page) {
1097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int flatten_ret = FPDFPage_Flatten(page, FLAT_PRINT);
1098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_ClosePage(page);
1099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (flatten_ret == FLATTEN_FAIL) {
1100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        flatten_succeeded = false;
1101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
1102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
1104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      flatten_succeeded = false;
1105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!flatten_succeeded) {
1109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(doc);
1110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
1111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Buffer_Dev buffer;
1114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumMemBufferFileWrite output_file_write;
1115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (FPDF_SaveAsCopy(doc, &output_file_write, 0)) {
1116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    buffer = pp::Buffer_Dev(
1117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        client_->GetPluginInstance(), output_file_write.size());
1118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!buffer.is_null()) {
1119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      memcpy(buffer.data(), output_file_write.buffer().c_str(),
1120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             output_file_write.size());
1121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return buffer;
1124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Buffer_Dev PDFiumEngine::PrintPagesAsPDF(
1127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
1128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintSettings_Dev& print_settings) {
1129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!page_range_count)
1130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
1131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(doc_);
1133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
1134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!output_doc)
1135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
1136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SaveSelectedFormForPrint();
1138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string page_number_str;
1140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (uint32_t index = 0; index < page_range_count; ++index) {
1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!page_number_str.empty())
1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_number_str.append(",");
1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_number_str.append(
1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::IntToString(page_ranges[index].first_page_number + 1));
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (page_ranges[index].first_page_number !=
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            page_ranges[index].last_page_number) {
1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_number_str.append("-");
1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_number_str.append(
1149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::IntToString(page_ranges[index].last_page_number + 1));
1150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<uint32_t> page_numbers =
1154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetPageNumbersFromPrintPageNumberRange(page_ranges, page_range_count);
1155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < page_numbers.size(); ++i) {
1156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32_t page_number = page_numbers[i];
1157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_[page_number]->GetPage();
1158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!IsPageVisible(page_numbers[i]))
1159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_number]->Unload();
1160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CopyViewerPreferences(output_doc, doc_);
1163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!FPDF_ImportPages(output_doc, doc_, page_number_str.c_str(), 0)) {
1164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(output_doc);
1165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return pp::Buffer_Dev();
1166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FitContentsToPrintableAreaIfRequired(output_doc, print_settings);
1169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Now flatten all the output pages.
1171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Buffer_Dev buffer = GetFlattenedPrintData(output_doc);
1172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CloseDocument(output_doc);
1173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return buffer;
1174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::FitContentsToPrintableAreaIfRequired(
1177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const FPDF_DOCUMENT& doc, const PP_PrintSettings_Dev& print_settings) {
1178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check to see if we need to fit pdf contents to printer paper size.
1179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (print_settings.print_scaling_option !=
1180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          PP_PRINTSCALINGOPTION_SOURCE_SIZE) {
1181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int num_pages = FPDF_GetPageCount(doc);
1182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // In-place transformation is more efficient than creating a new
1183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // transformed document from the source document. Therefore, transform
1184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // every page to fit the contents in the selected printer paper.
1185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int i = 0; i < num_pages; ++i) {
1186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_PAGE page = FPDF_LoadPage(doc, i);
1187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      TransformPDFPageForPrinting(page, print_settings);
1188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_ClosePage(page);
1189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SaveSelectedFormForPrint() {
1194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FORM_ForceToKillFocus(form_);
1195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->FormTextFieldFocusChange(false);
1196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PrintEnd() {
1199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP);
1200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumPage::Area PDFiumEngine::GetCharIndex(
1203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const pp::MouseInputEvent& event, int* page_index,
1204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int* char_index, PDFiumPage::LinkTarget* target) {
1205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // First figure out which page this is in.
1206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Point mouse_point = event.GetPosition();
1207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Point point(
1208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<int>((mouse_point.x() + position_.x()) / current_zoom_),
1209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<int>((mouse_point.y() + position_.y()) / current_zoom_));
1210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetCharIndex(point, page_index, char_index, target);
1211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumPage::Area PDFiumEngine::GetCharIndex(
1214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const pp::Point& point,
1215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int* page_index,
1216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int* char_index,
1217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PDFiumPage::LinkTarget* target) {
1218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page = -1;
1219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < visible_pages_.size(); ++i) {
1220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pages_[visible_pages_[i]]->rect().Contains(point)) {
1221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page = visible_pages_[i];
1222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page == -1)
1226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return PDFiumPage::NONSELECTABLE_AREA;
1227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the page hasn't finished rendering, calling into the page sometimes
1229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // leads to hangs.
1230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < progressive_paints_.size(); ++i) {
1231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (progressive_paints_[i].page_index == page)
1232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return PDFiumPage::NONSELECTABLE_AREA;
1233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *page_index = page;
1236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return pages_[page]->GetCharIndex(point, current_rotation_, char_index,
1237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    target);
1238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) {
1241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT)
1242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SelectionChangeInvalidator selection_invalidator(this);
1245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = -1;
1248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int char_index = -1;
1249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumPage::LinkTarget target;
1250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumPage::Area area = GetCharIndex(event, &page_index,
1251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       &char_index, &target);
1252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (area == PDFiumPage::WEBLINK_AREA) {
1253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool open_in_new_tab = !!(event.GetModifiers() & kDefaultKeyModifier);
1254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->NavigateTo(target.url, open_in_new_tab);
1255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->FormTextFieldFocusChange(false);
1256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
1257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (area == PDFiumPage::DOCLINK_AREA) {
1260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->ScrollToPage(target.page);
1261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->FormTextFieldFocusChange(false);
1262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
1263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_index != -1) {
1266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    last_page_mouse_down_ = page_index;
1267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double page_x, page_y;
1268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Point point = event.GetPosition();
1269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
1270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FORM_OnLButtonDown(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
1272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int control = FPDPage_HasFormFieldAtPoint(
1273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        form_, pages_[page_index]->GetPage(), page_x, page_y);
1274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (control > FPDF_FORMFIELD_UNKNOWN) {  // returns -1 sometimes...
1275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      client_->FormTextFieldFocusChange(control == FPDF_FORMFIELD_TEXTFIELD ||
1276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          control == FPDF_FORMFIELD_COMBOBOX);
1277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return true;  // Return now before we get into the selection code.
1278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->FormTextFieldFocusChange(false);
1282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (area != PDFiumPage::TEXT_AREA)
1284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;  // Return true so WebKit doesn't do its own highlighting.
1285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.GetClickCount() == 1) {
1287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    OnSingleClick(page_index, char_index);
1288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (event.GetClickCount() == 2 ||
1289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             event.GetClickCount() == 3) {
1290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    OnMultipleClick(event.GetClickCount(), page_index, char_index);
1291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
1294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnSingleClick(int page_index, int char_index) {
1297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selecting_ = true;
1298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.push_back(PDFiumRange(pages_[page_index], char_index, 0));
1299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnMultipleClick(int click_count,
1302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   int page_index,
1303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   int char_index) {
1304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // It would be more efficient if the SDK could support finding a space, but
1305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // now it doesn't.
1306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int start_index = char_index;
1307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  do {
1308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index);
1309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // For double click, we want to select one word so we look for whitespace
1310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // boundaries.  For triple click, we want the whole line.
1311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t')))
1312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } while (--start_index >= 0);
1314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (start_index)
1315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    start_index++;
1316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int end_index = char_index;
1318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int total = pages_[page_index]->GetCharCount();
1319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (end_index++ <= total) {
1320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index);
1321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t')))
1322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.push_back(PDFiumRange(
1326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index], start_index, end_index - start_index));
1327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
1330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT)
1331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = -1;
1334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int char_index = -1;
1335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetCharIndex(event, &page_index, &char_index, NULL);
1336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_index != -1) {
1337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double page_x, page_y;
1338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Point point = event.GetPosition();
1339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
1340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FORM_OnLButtonUp(
1341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
1342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!selecting_)
1345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selecting_ = false;
1348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
1349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
1352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = -1;
1353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int char_index = -1;
1354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumPage::Area area = GetCharIndex(event, &page_index, &char_index, NULL);
1355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!selecting_) {
1356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PP_CursorType_Dev cursor;
1357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch (area) {
1358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case PDFiumPage::TEXT_AREA:
1359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        cursor = PP_CURSORTYPE_IBEAM;
1360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
1361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case PDFiumPage::WEBLINK_AREA:
1362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case PDFiumPage::DOCLINK_AREA:
1363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        cursor = PP_CURSORTYPE_HAND;
1364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
1365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case PDFiumPage::NONSELECTABLE_AREA:
1366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      default:
1367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        cursor = PP_CURSORTYPE_POINTER;
1368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
1369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (page_index != -1) {
1372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      double page_x, page_y;
1373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pp::Point point = event.GetPosition();
1374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
1375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
1377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int control = FPDPage_HasFormFieldAtPoint(
1378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          form_, pages_[page_index]->GetPage(), page_x, page_y);
1379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      switch (control) {
1380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_PUSHBUTTON:
1381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_CHECKBOX:
1382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_RADIOBUTTON:
1383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_COMBOBOX:
1384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_LISTBOX:
1385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          cursor = PP_CURSORTYPE_HAND;
1386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          break;
1387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        case FPDF_FORMFIELD_TEXTFIELD:
1388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          cursor = PP_CURSORTYPE_IBEAM;
1389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          break;
1390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        default:
1391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          break;
1392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->UpdateCursor(cursor);
1396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Point point = event.GetPosition();
1397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string url = GetLinkAtPosition(event.GetPosition());
1398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (url != link_under_cursor_) {
1399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      link_under_cursor_ = url;
1400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pp::PDF::SetLinkUnderCursor(GetPluginInstance(), url.c_str());
1401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // No need to swallow the event, since this might interfere with the
1403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // scrollbars if the user is dragging them.
1404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We're selecting but right now we're not over text, so don't change the
1408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // current selection.
1409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (area != PDFiumPage::TEXT_AREA && area != PDFiumPage::WEBLINK_AREA &&
1410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      area != PDFiumPage::DOCLINK_AREA) {
1411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SelectionChangeInvalidator selection_invalidator(this);
1415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check if the user has descreased their selection area and we need to remove
1417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // pages from selection_.
1418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < selection_.size(); ++i) {
1419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (selection_[i].page_index() == page_index) {
1420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // There should be no other pages after this.
1421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selection_.erase(selection_.begin() + i + 1, selection_.end());
1422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (selection_.size() == 0)
1427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int last = selection_.size() - 1;
1430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (selection_[last].page_index() == page_index) {
1431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Selecting within a page.
1432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int count;
1433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (char_index >= selection_[last].char_index()) {
1434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Selecting forward.
1435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      count = char_index - selection_[last].char_index() + 1;
1436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
1437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      count = char_index - selection_[last].char_index() - 1;
1438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selection_[last].SetCharCount(count);
1440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (selection_[last].page_index() < page_index) {
1441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Selecting into the next page.
1442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // First make sure that there are no gaps in selection, i.e. if mousedown on
1444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // page one but we only get mousemove over page three, we want page two.
1445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int i = selection_[last].page_index() + 1; i < page_index; ++i) {
1446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selection_.push_back(PDFiumRange(pages_[i], 0,
1447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           pages_[i]->GetCharCount()));
1448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int count = pages_[selection_[last].page_index()]->GetCharCount();
1451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selection_[last].SetCharCount(count - selection_[last].char_index());
1452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selection_.push_back(PDFiumRange(pages_[page_index], 0, char_index));
1453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Selecting into the previous page.
1455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selection_[last].SetCharCount(-selection_[last].char_index());
1456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // First make sure that there are no gaps in selection, i.e. if mousedown on
1458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // page three but we only get mousemove over page one, we want page two.
1459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int i = selection_[last].page_index() - 1; i > page_index; --i) {
1460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selection_.push_back(PDFiumRange(pages_[i], 0,
1461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           pages_[i]->GetCharCount()));
1462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int count = pages_[page_index]->GetCharCount();
1465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    selection_.push_back(
1466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PDFiumRange(pages_[page_index], count, count - char_index));
1467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
1470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) {
1473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (last_page_mouse_down_ == -1)
1474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool rv = !!FORM_OnKeyDown(
1477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_, pages_[last_page_mouse_down_]->GetPage(),
1478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      event.GetKeyCode(), event.GetModifiers());
1479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.GetKeyCode() == ui::VKEY_BACK ||
1481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      event.GetKeyCode() == ui::VKEY_ESCAPE) {
1482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Chrome doesn't send char events for backspace or escape keys, see
1483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // PlatformKeyboardEventBuilder::isCharacterKey() and
1484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // http://chrome-corpsvn.mtv.corp.google.com/viewvc?view=rev&root=chrome&revision=31805
1485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // for more information.  So just fake one since PDFium uses it.
1486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string str;
1487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    str.push_back(event.GetKeyCode());
1488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::KeyboardInputEvent synthesized(pp::KeyboardInputEvent(
1489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        client_->GetPluginInstance(),
1490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PP_INPUTEVENT_TYPE_CHAR,
1491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        event.GetTimeStamp(),
1492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        event.GetModifiers(),
1493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        event.GetKeyCode(),
1494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        str));
1495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    OnChar(synthesized);
1496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv;
1499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnKeyUp(const pp::KeyboardInputEvent& event) {
1502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (last_page_mouse_down_ == -1)
1503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return !!FORM_OnKeyUp(
1506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_, pages_[last_page_mouse_down_]->GetPage(),
1507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      event.GetKeyCode(), event.GetModifiers());
1508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) {
1511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (last_page_mouse_down_ == -1)
1512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 str = base::UTF8ToUTF16(event.GetCharacterText().AsString());
1515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return !!FORM_OnChar(
1516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_, pages_[last_page_mouse_down_]->GetPage(),
1517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      str[0],
1518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      event.GetModifiers());
1519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::StartFind(const char* text, bool case_sensitive) {
1522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We can get a call to StartFind before we have any page information (i.e.
1523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // before the first call to LoadDocument has happened). Handle this case.
1524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (pages_.empty())
1525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool first_search = false;
1528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int character_to_start_searching_from = 0;
1529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (current_find_text_ != text) {  // First time we search for this text.
1530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    first_search = true;
1531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<PDFiumRange> old_selection = selection_;
1532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    StopFind();
1533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_find_text_ = text;
1534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (old_selection.empty()) {
1536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Start searching from the beginning of the document.
1537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      next_page_to_search_ = 0;
1538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_page_to_search_ = pages_.size() - 1;
1539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_character_index_to_search_ = -1;
1540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
1541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // There's a current selection, so start from it.
1542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      next_page_to_search_ = old_selection[0].page_index();
1543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_character_index_to_search_ = old_selection[0].char_index();
1544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      character_to_start_searching_from = old_selection[0].char_index();
1545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      last_page_to_search_ = next_page_to_search_;
1546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int current_page = next_page_to_search_;
1550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (pages_[current_page]->available()) {
1552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::string16 str = base::UTF8ToUTF16(text);
1553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't use PDFium to search for now, since it doesn't support unicode text.
1554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Leave the code for now to avoid bit-rot, in case it's fixed later.
1555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (0) {
1556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      SearchUsingPDFium(
1557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          str, case_sensitive, first_search, character_to_start_searching_from,
1558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          current_page);
1559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
1560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      SearchUsingICU(
1561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          str, case_sensitive, first_search, character_to_start_searching_from,
1562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          current_page);
1563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!IsPageVisible(current_page))
1566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[current_page]->Unload();
1567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (next_page_to_search_ != last_page_to_search_ ||
1570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (first_search && last_character_index_to_search_ != -1)) {
1571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++next_page_to_search_;
1572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (next_page_to_search_ == static_cast<int>(pages_.size()))
1575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    next_page_to_search_ = 0;
1576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If there's only one page in the document and we start searching midway,
1577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // then we'll want to search the page one more time.
1578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool end_of_search =
1579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      next_page_to_search_ == last_page_to_search_ &&
1580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Only one page but didn't start midway.
1581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ((pages_.size() == 1 && last_character_index_to_search_ == -1) ||
1582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       // Started midway, but only 1 page and we already looped around.
1583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       (pages_.size() == 1 && !first_search) ||
1584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       // Started midway, and we've just looped around.
1585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       (pages_.size() > 1 && current_page == next_page_to_search_));
1586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (end_of_search) {
1588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Send the final notification.
1589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->NotifyNumberOfFindResultsChanged(find_results_.size(), true);
1590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::CompletionCallback callback =
1592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        find_factory_.NewCallback(&PDFiumEngine::ContinueFind);
1593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Module::Get()->core()->CallOnMainThread(
1594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        0, callback, case_sensitive ? 1 : 0);
1595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SearchUsingPDFium(const base::string16& term,
1599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     bool case_sensitive,
1600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     bool first_search,
1601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int character_to_start_searching_from,
1602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int current_page) {
1603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Find all the matches in the current page.
1604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unsigned long flags = case_sensitive ? FPDF_MATCHCASE : 0;
1605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_SCHHANDLE find = FPDFText_FindStart(
1606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[current_page]->GetTextPage(),
1607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reinterpret_cast<const unsigned short*>(term.c_str()),
1608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      flags, character_to_start_searching_from);
1609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Note: since we search one page at a time, we don't find matches across
1611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // page boundaries.  We could do this manually ourself, but it seems low
1612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // priority since Reader itself doesn't do it.
1613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (FPDFText_FindNext(find)) {
1614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PDFiumRange result(pages_[current_page],
1615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       FPDFText_GetSchResultIndex(find),
1616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       FPDFText_GetSchCount(find));
1617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!first_search &&
1619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        last_character_index_to_search_ != -1 &&
1620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        result.page_index() == last_page_to_search_ &&
1621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        result.char_index() >= last_character_index_to_search_) {
1622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AddFindResult(result);
1626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFText_FindClose(find);
1629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SearchUsingICU(const base::string16& term,
1632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  bool case_sensitive,
1633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  bool first_search,
1634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  int character_to_start_searching_from,
1635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  int current_page) {
1636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 page_text;
1637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int text_length = pages_[current_page]->GetCharCount();
1638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (character_to_start_searching_from) {
1639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    text_length -= character_to_start_searching_from;
1640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (!first_search &&
1641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             last_character_index_to_search_ != -1 &&
1642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             current_page == last_page_to_search_) {
1643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    text_length = last_character_index_to_search_;
1644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (text_length <= 0)
1646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unsigned short* data =
1648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reinterpret_cast<unsigned short*>(WriteInto(&page_text, text_length + 1));
1649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFText_GetText(pages_[current_page]->GetTextPage(),
1650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   character_to_start_searching_from,
1651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   text_length,
1652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   data);
1653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<PDFEngine::Client::SearchStringResult> results;
1654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->SearchString(
1655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_text.c_str(), term.c_str(), case_sensitive, &results);
1656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < results.size(); ++i) {
1657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Need to map the indexes from the page text, which may have generated
1658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // characters like space etc, to character indices from the page.
1659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int temp_start = results[i].start_index + character_to_start_searching_from;
1660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int start = FPDFText_GetCharIndexFromTextIndex(
1661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[current_page]->GetTextPage(), temp_start);
1662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int end = FPDFText_GetCharIndexFromTextIndex(
1663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[current_page]->GetTextPage(),
1664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        temp_start + results[i].length);
1665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AddFindResult(PDFiumRange(pages_[current_page], start, end - start));
1666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::AddFindResult(const PDFiumRange& result) {
1670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Figure out where to insert the new location, since we could have
1671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // started searching midway and now we wrapped.
1672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t i;
1673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = result.page_index();
1674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int char_index = result.char_index();
1675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (i = 0; i < find_results_.size(); ++i) {
1676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (find_results_[i].page_index() > page_index ||
1677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        (find_results_[i].page_index() == page_index &&
1678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         find_results_[i].char_index() > char_index)) {
1679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_results_.insert(find_results_.begin() + i, result);
1683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateTickMarks();
1684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (current_find_index_ == -1) {
1686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Select the first match.
1687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SelectFindResult(true);
1688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (static_cast<int>(i) <= current_find_index_) {
1689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Update the current match index
1690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_find_index_++;
1691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->NotifySelectedFindResultChanged(current_find_index_);
1692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->NotifyNumberOfFindResultsChanged(find_results_.size(), false);
1694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::SelectFindResult(bool forward) {
1697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (find_results_.empty()) {
1698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
1699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SelectionChangeInvalidator selection_invalidator(this);
1703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Move back/forward through the search locations we previously found.
1705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (forward) {
1706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (++current_find_index_ == static_cast<int>(find_results_.size()))
1707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_find_index_ = 0;
1708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (--current_find_index_ < 0) {
1710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_find_index_ = find_results_.size() - 1;
1711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the selection before telling the client to scroll, since it could
1715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // paint then.
1716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.push_back(find_results_[current_find_index_]);
1718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the result is not in view, scroll to it.
1720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t i;
1721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect bounding_rect;
1722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect visible_rect = GetVisibleRect();
1723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Use zoom of 1.0 since visible_rect is without zoom.
1724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> rects = find_results_[current_find_index_].
1725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetScreenRects(pp::Point(), 1.0, current_rotation_);
1726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (i = 0; i < rects.size(); ++i)
1727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bounding_rect = bounding_rect.Union(rects[i]);
1728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!visible_rect.Contains(bounding_rect)) {
1729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Point center = bounding_rect.CenterPoint();
1730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Make the page centered.
1731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int new_y = static_cast<int>(center.y() * current_zoom_) -
1732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                static_cast<int>(visible_rect.height() * current_zoom_ / 2);
1733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (new_y < 0)
1734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new_y = 0;
1735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->ScrollToY(new_y);
1736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only move horizontally if it's not visible.
1738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (center.x() < visible_rect.x() || center.x() > visible_rect.right()) {
1739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int new_x = static_cast<int>(center.x()  * current_zoom_) -
1740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  static_cast<int>(visible_rect.width() * current_zoom_ / 2);
1741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (new_x < 0)
1742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new_x = 0;
1743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      client_->ScrollToX(new_x);
1744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->NotifySelectedFindResultChanged(current_find_index_);
1748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
1750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::StopFind() {
1753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SelectionChangeInvalidator selection_invalidator(this);
1754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1756cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selecting_ = false;
1757cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_results_.clear();
1758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  next_page_to_search_ = -1;
1759cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  last_page_to_search_ = -1;
1760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  last_character_index_to_search_ = -1;
1761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_find_index_ = -1;
1762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_find_text_.clear();
1763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateTickMarks();
1764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_factory_.CancelAll();
1765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::UpdateTickMarks() {
1768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> tickmarks;
1769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < find_results_.size(); ++i) {
1770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rect;
1771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Always use an origin of 0,0 since scroll positions don't affect tickmark.
1772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<pp::Rect> rects = find_results_[i].GetScreenRects(
1773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pp::Point(0, 0), current_zoom_, current_rotation_);
1774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t j = 0; j < rects.size(); ++j)
1775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rect = rect.Union(rects[j]);
1776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    tickmarks.push_back(rect);
1777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->UpdateTickMarks(tickmarks);
1780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::ZoomUpdated(double new_zoom_level) {
1783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CancelPaints();
1784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_zoom_ = new_zoom_level;
1786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
1788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateTickMarks();
1789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::RotateClockwise() {
1792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_rotation_ = (current_rotation_ + 1) % 4;
1793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InvalidateAllPages();
1794cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::RotateCounterclockwise() {
1797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  current_rotation_ = (current_rotation_ - 1) % 4;
1798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InvalidateAllPages();
1799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::InvalidateAllPages() {
1802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_results_.clear();
1804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CancelPaints();
1806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoadPageInfo(true);
1807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateTickMarks();
1808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->Invalidate(pp::Rect(plugin_size_));
1809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string PDFiumEngine::GetSelectedText() {
1812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 result;
1813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < selection_.size(); ++i) {
1814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (i > 0 &&
1815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        selection_[i - 1].page_index() > selection_[i].page_index()) {
1816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      result = selection_[i].GetText() + result;
1817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
1818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      result.append(selection_[i].GetText());
1819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return base::UTF16ToUTF8(result);
1823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string PDFiumEngine::GetLinkAtPosition(const pp::Point& point) {
1826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int temp;
1827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumPage::LinkTarget target;
1828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumPage::Area area = GetCharIndex(point, &temp, &temp, &target);
1829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (area == PDFiumPage::WEBLINK_AREA)
1830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return target.url;
1831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return std::string();
1832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::IsSelecting() {
1835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return selecting_;
1836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::HasPermission(DocumentPermission permission) const {
1839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (permission) {
1840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PERMISSION_COPY:
1841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return (permissions_ & kPDFPermissionCopyMask) != 0;
1842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PERMISSION_COPY_ACCESSIBLE:
1843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return (permissions_ & kPDFPermissionCopyAccessibleMask) != 0;
1844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PERMISSION_PRINT_LOW_QUALITY:
1845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0;
1846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case PERMISSION_PRINT_HIGH_QUALITY:
1847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0 &&
1848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             (permissions_ & kPDFPermissionPrintHighQualityMask) != 0;
1849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
1850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return true;
1851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
1852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SelectAll() {
1855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SelectionChangeInvalidator selection_invalidator(this);
1856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < pages_.size(); ++i)
1859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pages_[i]->available()) {
1860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selection_.push_back(PDFiumRange(pages_[i], 0,
1861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           pages_[i]->GetCharCount()));
1862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetNumberOfPages() {
1866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return pages_.size();
1867cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetNamedDestinationPage(const std::string& destination) {
1870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Look for the destination.
1871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DEST dest = FPDF_GetNamedDestByName(doc_, destination.c_str());
1872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!dest) {
1873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Look for a bookmark with the same name.
1874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::string16 destination_wide = base::UTF8ToUTF16(destination);
1875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_WIDESTRING destination_pdf_wide =
1876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        reinterpret_cast<FPDF_WIDESTRING>(destination_wide.c_str());
1877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_BOOKMARK bookmark = FPDFBookmark_Find(doc_, destination_pdf_wide);
1878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!bookmark)
1879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return -1;
1880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    dest = FPDFBookmark_GetDest(doc_, bookmark);
1881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return dest ? FPDFDest_GetPageIndex(doc_, dest) : -1;
1883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetFirstVisiblePage() {
1886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
1887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return first_visible_page_;
1888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetMostVisiblePage() {
1891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
1892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return most_visible_page_;
1893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Rect PDFiumEngine::GetPageRect(int index) {
1896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect rc(pages_[index]->rect());
1897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rc.Inset(-kPageShadowLeft, -kPageShadowTop,
1898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)           -kPageShadowRight, -kPageShadowBottom);
1899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rc;
1900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Rect PDFiumEngine::GetPageContentsRect(int index) {
1903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetScreenRect(pages_[index]->rect());
1904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PaintThumbnail(pp::ImageData* image_data, int index) {
1907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(
1908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      image_data->size().width(), image_data->size().height(),
1909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDFBitmap_BGRx, image_data->data(), image_data->stride());
1910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (pages_[index]->available()) {
1912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(
1913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, 0, 0, image_data->size().width(), image_data->size().height(),
1914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        255, 255, 255, 255);
1915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPageBitmap(
1917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, pages_[index]->GetPage(), 0, 0, image_data->size().width(),
1918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        image_data->size().height(), 0, GetRenderingFlags());
1919cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(
1921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, 0, 0, image_data->size().width(), image_data->size().height(),
1922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kPendingPageColorR, kPendingPageColorG, kPendingPageColorB,
1923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kPendingPageColorA);
1924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_Destroy(bitmap);
1927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SetGrayscale(bool grayscale) {
1930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  render_grayscale_ = grayscale;
1931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnCallback(int id) {
1934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!timers_.count(id))
1935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  timers_[id].second(id);
1938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (timers_.count(id))  // The callback might delete the timer.
1939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->ScheduleCallback(id, timers_[id].first);
1940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string PDFiumEngine::GetPageAsJSON(int index) {
1943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!(HasPermission(PERMISSION_COPY) ||
1944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        HasPermission(PERMISSION_COPY_ACCESSIBLE))) {
1945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "{}";
1946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (index < 0 || static_cast<size_t>(index) > pages_.size() - 1)
1949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "{}";
1950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::Value> node(
1952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[index]->GetAccessibleContentAsValue(current_rotation_));
1953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string page_json;
1954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::JSONWriter::Write(node.get(), &page_json);
1955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return page_json;
1956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::GetPrintScaling() {
1959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return !!FPDF_VIEWERREF_GetPrintScaling(doc_);
1960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::AppendBlankPages(int num_pages) {
1963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(num_pages != 0);
1964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_)
1966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  selection_.clear();
1969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_pages_.clear();
1970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Delete all pages except the first one.
1972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (pages_.size() > 1) {
1973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    delete pages_.back();
1974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_.pop_back();
1975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPage_Delete(doc_, pages_.size());
1976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Calculate document size and all page sizes.
1979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> page_rects;
1980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size page_size = GetPageSize(0);
1981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_size.Enlarge(kPageShadowLeft + kPageShadowRight,
1982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    kPageShadowTop + kPageShadowBottom);
1983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size old_document_size = document_size_;
1984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  document_size_ = pp::Size(page_size.width(), 0);
1985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 0; i < num_pages; ++i) {
1986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (i != 0) {
1987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Add space for horizontal separator.
1988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      document_size_.Enlarge(0, kPageSeparatorThickness);
1989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rect(pp::Point(0, document_size_.height()), page_size);
1992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_rects.push_back(rect);
1993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    document_size_.Enlarge(0, page_size.height());
1995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create blank pages.
1998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 1; i < num_pages; ++i) {
1999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect page_rect(page_rects[i]);
2000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_rect.Inset(kPageShadowLeft, kPageShadowTop,
2001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    kPageShadowRight, kPageShadowBottom);
2002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double width_in_points =
2003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        page_rect.width() * kPointsPerInch / kPixelsPerInch;
2004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double height_in_points =
2005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        page_rect.height() * kPointsPerInch / kPixelsPerInch;
2006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFPage_New(doc_, i, width_in_points, height_in_points);
2007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_.push_back(new PDFiumPage(this, i, page_rect, true));
2008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
2011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (document_size_ != old_document_size)
2012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentSizeUpdated(document_size_);
2013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::LoadDocument() {
2016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check if the document is ready for loading. If it isn't just bail for now,
2017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // we will call LoadDocument() again later.
2018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_ && !doc_loader_.IsDocumentComplete() &&
2019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !FPDFAvail_IsDocAvail(fpdf_availability_, &download_hints_)) {
2020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we're in the middle of getting a password, just return. We will retry
2024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // loading the document after we get the password anyway.
2025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (getting_password_)
2026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedUnsupportedFeature scoped_unsupported_feature(this);
2029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool needs_password = false;
2030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (TryLoadingDoc(false, std::string(), &needs_password)) {
2031cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ContinueLoadingDocument(false, std::string());
2032cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2033cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2034cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (needs_password)
2035cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GetPasswordAndLoad();
2036cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
2037cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentLoadFailed();
2038cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2039cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2040cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::TryLoadingDoc(bool with_password,
2041cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 const std::string& password,
2042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 bool* needs_password) {
2043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *needs_password = false;
2044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_)
2045cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
2046cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2047cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* password_cstr = NULL;
2048cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (with_password) {
2049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    password_cstr = password.c_str();
2050cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    password_tries_remaining_--;
2051cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2052cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_loader_.IsDocumentComplete())
2053cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    doc_ = FPDF_LoadCustomDocument(&file_access_, password_cstr);
2054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
2055cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    doc_ = FPDFAvail_GetDocument(fpdf_availability_, password_cstr);
2056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD)
2058cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *needs_password = true;
2059cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2060cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return doc_ != NULL;
2061cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2062cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2063cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::GetPasswordAndLoad() {
2064cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  getting_password_ = true;
2065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD);
2066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->GetDocumentPassword(password_factory_.NewCallbackWithOutput(
2067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &PDFiumEngine::OnGetPasswordComplete));
2068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnGetPasswordComplete(int32_t result,
2071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         const pp::Var& password) {
2072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  getting_password_ = false;
2073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool password_given = false;
2075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string password_text;
2076cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (result == PP_OK && password.is_string()) {
2077cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    password_text = password.AsString();
2078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!password_text.empty())
2079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      password_given = true;
2080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ContinueLoadingDocument(password_given, password_text);
2082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::ContinueLoadingDocument(
2085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool has_password,
2086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& password) {
2087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedUnsupportedFeature scoped_unsupported_feature(this);
2088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool needs_password = false;
2090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool loaded = TryLoadingDoc(has_password, password, &needs_password);
2091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool password_incorrect = !loaded && has_password && needs_password;
2092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (password_incorrect && password_tries_remaining_ > 0) {
2093cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GetPasswordAndLoad();
2094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_) {
2098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentLoadFailed();
2099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (FPDFDoc_GetPageMode(doc_) == PAGEMODE_USEOUTLINES)
2103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentHasUnsupportedFeature("Bookmarks");
2104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  permissions_ = FPDF_GetDocPermissions(doc_);
2106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!form_) {
2108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only returns 0 when data isn't available.  If form data is downloaded, or
2109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // if this isn't a form, returns positive values.
2110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!doc_loader_.IsDocumentComplete() &&
2111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !FPDFAvail_IsFormAvail(fpdf_availability_, &download_hints_)) {
2112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
2113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    form_ = FPDFDOC_InitFormFillEnviroument(
2116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        doc_, static_cast<FPDF_FORMFILLINFO*>(this));
2117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_SetFormFieldHighlightColor(form_, 0, kFormHighlightColor);
2118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_SetFormFieldHighlightAlpha(form_, kFormHighlightAlpha);
2119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_loader_.IsDocumentComplete()) {
2122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Check if the first page is available.  In a linearized PDF, that is not
2123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // always page 0.  Doing this gives us the default page size, since when the
2124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // document is available, the first page is available as well.
2125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckPageAvailable(FPDFAvail_GetFirstPageNum(doc_), &pending_pages_);
2126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoadPageInfo(false);
2129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (doc_loader_.IsDocumentComplete())
2131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FinishLoadingDocument();
2132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::LoadPageInfo(bool reload) {
2135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_pages_.clear();
2136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size old_document_size = document_size_;
2137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  document_size_ = pp::Size();
2138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> page_rects;
2139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_count = FPDF_GetPageCount(doc_);
2140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool doc_complete = doc_loader_.IsDocumentComplete();
2141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 0; i < page_count; ++i) {
2142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (i != 0) {
2143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Add space for horizontal separator.
2144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      document_size_.Enlarge(0, kPageSeparatorThickness);
2145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Get page availability. If reload==false, and document is not loaded yet
2148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // (we are using async loading) - mark all pages as unavailable.
2149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // If reload==true (we have document constructed already), get page
2150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // availability flag from already existing PDFiumPage class.
2151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool page_available = reload ? pages_[i]->available() : doc_complete;
2152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Size size = page_available ? GetPageSize(i) : default_page_size_;
2154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size.Enlarge(kPageShadowLeft + kPageShadowRight,
2155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 kPageShadowTop + kPageShadowBottom);
2156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rect(pp::Point(0, document_size_.height()), size);
2157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_rects.push_back(rect);
2158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (size.width() > document_size_.width())
2160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      document_size_.set_width(size.width());
2161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    document_size_.Enlarge(0, size.height());
2163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 0; i < page_count; ++i) {
2166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Center pages relative to the entire document.
2167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_rects[i].set_x((document_size_.width() - page_rects[i].width()) / 2);
2168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect page_rect(page_rects[i]);
2169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_rect.Inset(kPageShadowLeft, kPageShadowTop,
2170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    kPageShadowRight, kPageShadowBottom);
2171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (reload) {
2172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[i]->set_rect(page_rect);
2173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
2174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_.push_back(new PDFiumPage(this, i, page_rect, doc_complete));
2175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateVisiblePages();
2179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (document_size_ != old_document_size)
2180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_->DocumentSizeUpdated(document_size_);
2181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::CalculateVisiblePages() {
2184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clear pending requests queue, since it may contain requests to the pages
2185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // that are already invisible (after scrolling for example).
2186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_pages_.clear();
2187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  doc_loader_.ClearPendingRequests();
2188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  visible_pages_.clear();
2190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect visible_rect(plugin_size_);
2191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < pages_.size(); ++i) {
2192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Check an entire PageScreenRect, since we might need to repaint side
2193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // borders and shadows even if the page itself is not visible.
2194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // For example, when user use pdf with different page sizes and zoomed in
2195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // outside page area.
2196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (visible_rect.Intersects(GetPageScreenRect(i))) {
2197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      visible_pages_.push_back(i);
2198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CheckPageAvailable(i, &pending_pages_);
2199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
2200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Need to unload pages when we're not using them, since some PDFs use a
2201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // lot of memory.  See http://crbug.com/48791
2202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (defer_page_unload_) {
2203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        deferred_page_unloads_.push_back(i);
2204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
2205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[i]->Unload();
2206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
2207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // If the last mouse down was on a page that's no longer visible, reset
2209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // that variable so that we don't send keyboard events to it (the focus
2210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // will be lost when the page is first closed anyways).
2211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (static_cast<int>(i) == last_page_mouse_down_)
2212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        last_page_mouse_down_ = -1;
2213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Any pending highlighting of form fields will be invalid since these are in
2217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // screen coordinates.
2218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  form_highlights_.clear();
2219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (visible_pages_.size() == 0)
2221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    first_visible_page_ = -1;
2222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
2223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    first_visible_page_ = visible_pages_.front();
2224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int most_visible_page = first_visible_page_;
2226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check if the next page is more visible than the first one.
2227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (most_visible_page != -1 &&
2228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_.size() > 0 &&
2229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      most_visible_page < static_cast<int>(pages_.size()) - 1) {
2230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rc_first =
2231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        visible_rect.Intersect(GetPageScreenRect(most_visible_page));
2232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect rc_next =
2233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        visible_rect.Intersect(GetPageScreenRect(most_visible_page + 1));
2234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (rc_next.height() > rc_first.height())
2235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      most_visible_page++;
2236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetCurrentPage(most_visible_page);
2239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::IsPageVisible(int index) const {
2242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < visible_pages_.size(); ++i) {
2243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (visible_pages_[i] == index)
2244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return true;
2245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
2248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::CheckPageAvailable(int index, std::vector<int>* pending) {
2251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc_ || !form_)
2252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
2253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (static_cast<int>(pages_.size()) > index && pages_[index]->available())
2255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
2256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!FPDFAvail_IsPageAvail(fpdf_availability_, index, &download_hints_)) {
2258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size_t j;
2259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (j = 0; j < pending->size(); ++j) {
2260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if ((*pending)[j] == index)
2261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
2262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (j == pending->size())
2265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pending->push_back(index);
2266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
2267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (static_cast<int>(pages_.size()) > index)
2270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pages_[index]->set_available(true);
2271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!default_page_size_.GetArea())
2272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default_page_size_ = GetPageSize(index);
2273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
2274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Size PDFiumEngine::GetPageSize(int index) {
2277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size size;
2278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double width_in_points = 0;
2279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double height_in_points = 0;
2280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rv = FPDF_GetPageSizeByIndex(
2281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      doc_, index, &width_in_points, &height_in_points);
2282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (rv) {
2284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int width_in_pixels = static_cast<int>(
2285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        width_in_points * kPixelsPerInch / kPointsPerInch);
2286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int height_in_pixels = static_cast<int>(
2287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        height_in_points * kPixelsPerInch / kPointsPerInch);
2288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (current_rotation_ % 2 == 1)
2289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::swap(width_in_pixels, height_in_pixels);
2290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size = pp::Size(width_in_pixels, height_in_pixels);
2291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return size;
2293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::StartPaint(int page_index, const pp::Rect& dirty) {
2296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // For the first time we hit paint, do nothing and just record the paint for
2297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the next callback.  This keeps the UI responsive in case the user is doing
2298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // a lot of scrolling.
2299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ProgressivePaint progressive;
2300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive.rect = dirty;
2301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive.page_index = page_index;
2302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive.bitmap = NULL;
2303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive.painted_ = false;
2304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive_paints_.push_back(progressive);
2305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return progressive_paints_.size() - 1;
2306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngine::ContinuePaint(int progressive_index,
2309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 pp::ImageData* image_data) {
2310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_LINUX)
2311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_last_instance_id = client_->GetPluginInstance()->pp_instance();
2312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
2313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rv;
2315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = progressive_paints_[progressive_index].page_index;
2316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  last_progressive_start_time_ = base::Time::Now();
2317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (progressive_paints_[progressive_index].bitmap) {
2318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rv = FPDF_RenderPage_Continue(
2319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[page_index]->GetPage(), static_cast<IFSDK_PAUSE*>(this));
2320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
2321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect dirty = progressive_paints_[progressive_index].rect;
2322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    progressive_paints_[progressive_index].bitmap = CreateBitmap(dirty,
2323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                                 image_data);
2324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int start_x, start_y, size_x, size_y;
2325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GetPDFiumRect(
2326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        page_index, dirty, &start_x, &start_y, &size_x, &size_y);
2327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(
2328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        progressive_paints_[progressive_index].bitmap, start_x, start_y, size_x,
2329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        size_y, 255, 255, 255, 255);
2330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rv = FPDF_RenderPageBitmap_Start(
2331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        progressive_paints_[progressive_index].bitmap,
2332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        pages_[page_index]->GetPage(), start_x, start_y, size_x, size_y,
2333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        current_rotation_,
2334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        GetRenderingFlags(), static_cast<IFSDK_PAUSE*>(this));
2335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv != FPDF_RENDER_TOBECOUNTINUED;
2337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::FinishPaint(int progressive_index,
2340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               pp::ImageData* image_data) {
2341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = progressive_paints_[progressive_index].page_index;
2342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
2344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int start_x, start_y, size_x, size_y;
2345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetPDFiumRect(
2346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_index, dirty_in_screen, &start_x, &start_y, &size_x, &size_y);
2347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Draw the forms.
2349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_FFLDraw(
2350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_, bitmap, pages_[page_index]->GetPage(), start_x, start_y, size_x,
2351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      size_y, current_rotation_, GetRenderingFlags());
2352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FillPageSides(progressive_index);
2354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Paint the page shadows.
2356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PaintPageShadow(progressive_index, image_data);
2357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DrawSelections(progressive_index, image_data);
2359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_RenderPage_Close(pages_[page_index]->GetPage());
2361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_Destroy(bitmap);
2362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive_paints_.erase(progressive_paints_.begin() + progressive_index);
2363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_->DocumentPaintOccurred();
2365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::CancelPaints() {
2368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < progressive_paints_.size(); ++i) {
2369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPage_Close(pages_[progressive_paints_[i].page_index]->GetPage());
2370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_Destroy(progressive_paints_[i].bitmap);
2371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  progressive_paints_.clear();
2373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::FillPageSides(int progressive_index) {
2376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = progressive_paints_[progressive_index].page_index;
2377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
2379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect page_rect = pages_[page_index]->rect();
2381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_rect.x() > 0) {
2382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect left(0,
2383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  page_rect.y() - kPageShadowTop,
2384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  page_rect.x() - kPageShadowLeft,
2385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  page_rect.height() + kPageShadowTop +
2386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      kPageShadowBottom + kPageSeparatorThickness);
2387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    left = GetScreenRect(left).Intersect(dirty_in_screen);
2388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(
2390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, left.x() - dirty_in_screen.x(),
2391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        left.y() - dirty_in_screen.y(), left.width(), left.height(),
2392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kBackgroundColorR, kBackgroundColorG, kBackgroundColorB,
2393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kBackgroundColorA);
2394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_rect.right() < document_size_.width()) {
2397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect right(page_rect.right() + kPageShadowRight,
2398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   page_rect.y() - kPageShadowTop,
2399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   document_size_.width() - page_rect.right() -
2400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      kPageShadowRight,
2401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   page_rect.height() + kPageShadowTop +
2402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       kPageShadowBottom + kPageSeparatorThickness);
2403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    right = GetScreenRect(right).Intersect(dirty_in_screen);
2404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(
2406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, right.x() - dirty_in_screen.x(),
2407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        right.y() - dirty_in_screen.y(), right.width(), right.height(),
2408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kBackgroundColorR, kBackgroundColorG, kBackgroundColorB,
2409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kBackgroundColorA);
2410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Paint separator.
2413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect bottom(page_rect.x() - kPageShadowLeft,
2414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  page_rect.bottom() + kPageShadowBottom,
2415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  page_rect.width() + kPageShadowLeft + kPageShadowRight,
2416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  kPageSeparatorThickness);
2417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bottom = GetScreenRect(bottom).Intersect(dirty_in_screen);
2418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_FillRect(
2420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bitmap, bottom.x() - dirty_in_screen.x(),
2421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bottom.y() - dirty_in_screen.y(), bottom.width(), bottom.height(),
2422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kBackgroundColorR, kBackgroundColorG, kBackgroundColorB,
2423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kBackgroundColorA);
2424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PaintPageShadow(int progressive_index,
2427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   pp::ImageData* image_data) {
2428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = progressive_paints_[progressive_index].page_index;
2429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect page_rect = pages_[page_index]->rect();
2431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect shadow_rect(page_rect);
2432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  shadow_rect.Inset(-kPageShadowLeft, -kPageShadowTop,
2433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    -kPageShadowRight, -kPageShadowBottom);
2434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Due to the rounding errors of the GetScreenRect it is possible to get
2436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // different size shadows on the left and right sides even they are defined
2437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the same. To fix this issue let's calculate shadow rect and then shrink
2438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // it by the size of the shadows.
2439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  shadow_rect = GetScreenRect(shadow_rect);
2440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_rect = shadow_rect;
2441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_rect.Inset(static_cast<int>(ceil(kPageShadowLeft * current_zoom_)),
2443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  static_cast<int>(ceil(kPageShadowTop * current_zoom_)),
2444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  static_cast<int>(ceil(kPageShadowRight * current_zoom_)),
2445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  static_cast<int>(ceil(kPageShadowBottom * current_zoom_)));
2446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DrawPageShadow(page_rect, shadow_rect, dirty_in_screen, image_data);
2448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::DrawSelections(int progressive_index,
2451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  pp::ImageData* image_data) {
2452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = progressive_paints_[progressive_index].page_index;
2453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void* region = NULL;
2456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int stride;
2457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetRegion(dirty_in_screen.point(), image_data, &region, &stride);
2458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> highlighted_rects;
2460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect visible_rect = GetVisibleRect();
2461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t k = 0; k < selection_.size(); ++k) {
2462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (selection_[k].page_index() != page_index)
2463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
2464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<pp::Rect> rects = selection_[k].GetScreenRects(
2465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        visible_rect.point(), current_zoom_, current_rotation_);
2466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t j = 0; j < rects.size(); ++j) {
2467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pp::Rect visible_selection = rects[j].Intersect(dirty_in_screen);
2468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (visible_selection.IsEmpty())
2469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        continue;
2470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      visible_selection.Offset(
2472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          -dirty_in_screen.point().x(), -dirty_in_screen.point().y());
2473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      Highlight(region, stride, visible_selection, &highlighted_rects);
2474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t k = 0; k < form_highlights_.size(); ++k) {
2478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Rect visible_selection = form_highlights_[k].Intersect(dirty_in_screen);
2479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (visible_selection.IsEmpty())
2480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        continue;
2481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    visible_selection.Offset(
2483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        -dirty_in_screen.point().x(), -dirty_in_screen.point().y());
2484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Highlight(region, stride, visible_selection, &highlighted_rects);
2485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  form_highlights_.clear();
2487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::PaintUnavailablePage(int page_index,
2490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        const pp::Rect& dirty,
2491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        pp::ImageData* image_data) {
2492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int start_x, start_y, size_x, size_y;
2493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetPDFiumRect(page_index, dirty, &start_x, &start_y, &size_x, &size_y);
2494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_BITMAP bitmap = CreateBitmap(dirty, image_data);
2495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_FillRect(bitmap, start_x, start_y, size_x, size_y,
2496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kPendingPageColorR, kPendingPageColorG, kPendingPageColorB,
2497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      kPendingPageColorA);
2498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect loading_text_in_screen(
2500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().width() / 2,
2501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().y() + kLoadingTextVerticalOffset, 0, 0);
2502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  loading_text_in_screen = GetScreenRect(loading_text_in_screen);
2503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_Destroy(bitmap);
2504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetProgressiveIndex(int page_index) const {
2507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < progressive_paints_.size(); ++i) {
2508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (progressive_paints_[i].page_index == page_index)
2509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return i;
2510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return -1;
2512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_BITMAP PDFiumEngine::CreateBitmap(const pp::Rect& rect,
2515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       pp::ImageData* image_data) const {
2516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void* region;
2517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int stride;
2518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetRegion(rect.point(), image_data, &region, &stride);
2519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!region)
2520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
2521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FPDFBitmap_CreateEx(
2522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rect.width(), rect.height(), FPDFBitmap_BGRx, region, stride);
2523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::GetPDFiumRect(
2526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int page_index, const pp::Rect& rect, int* start_x, int* start_y,
2527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int* size_x, int* size_y) const {
2528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect page_rect = GetScreenRect(pages_[page_index]->rect());
2529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_rect.Offset(-rect.x(), -rect.y());
2530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *start_x = page_rect.x();
2532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *start_y = page_rect.y();
2533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *size_x = page_rect.width();
2534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *size_y = page_rect.height();
2535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetRenderingFlags() const {
2538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int flags = FPDF_LCD_TEXT | FPDF_NO_CATCH;
2539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (render_grayscale_)
2540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    flags |= FPDF_GRAYSCALE;
2541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (client_->IsPrintPreview())
2542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    flags |= FPDF_PRINTING;
2543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return flags;
2544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Rect PDFiumEngine::GetVisibleRect() const {
2547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect rv;
2548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_x(static_cast<int>(position_.x() / current_zoom_));
2549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_y(static_cast<int>(position_.y() / current_zoom_));
2550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_width(static_cast<int>(ceil(plugin_size_.width() / current_zoom_)));
2551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_height(static_cast<int>(ceil(plugin_size_.height() / current_zoom_)));
2552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv;
2553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Rect PDFiumEngine::GetPageScreenRect(int page_index) const {
2556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Since we use this rect for creating the PDFium bitmap, also include other
2557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // areas around the page that we might need to update such as the page
2558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // separator and the sides if the page is narrower than the document.
2559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetScreenRect(pp::Rect(
2560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      0,
2561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().y() - kPageShadowTop,
2562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      document_size_.width(),
2563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().height() + kPageShadowTop +
2564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kPageShadowBottom + kPageSeparatorThickness));
2565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)pp::Rect PDFiumEngine::GetScreenRect(const pp::Rect& rect) const {
2568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect rv;
2569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int right =
2570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<int>(ceil(rect.right() * current_zoom_ - position_.x()));
2571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int bottom =
2572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    static_cast<int>(ceil(rect.bottom() * current_zoom_ - position_.y()));
2573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_x(static_cast<int>(rect.x() * current_zoom_ - position_.x()));
2575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_y(static_cast<int>(rect.y() * current_zoom_ - position_.y()));
2576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_width(right - rv.x());
2577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.set_height(bottom - rv.y());
2578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv;
2579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Highlight(void* buffer,
2582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int stride,
2583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const pp::Rect& rect,
2584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             std::vector<pp::Rect>* highlighted_rects) {
2585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!buffer)
2586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect new_rect = rect;
2589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < highlighted_rects->size(); ++i)
2590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    new_rect = new_rect.Subtract((*highlighted_rects)[i]);
2591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  highlighted_rects->push_back(new_rect);
2593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int l = new_rect.x();
2594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int t = new_rect.y();
2595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int w = new_rect.width();
2596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int h = new_rect.height();
2597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int y = t; y < t + h; ++y) {
2599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int x = l; x < l + w; ++x) {
2600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      uint8* pixel = static_cast<uint8*>(buffer) + y * stride + x * 4;
2601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      //  This is our highlight color.
2602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pixel[0] = static_cast<uint8>(
2603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          pixel[0] * (kHighlightColorB / 255.0));
2604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pixel[1] = static_cast<uint8>(
2605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          pixel[1] * (kHighlightColorG / 255.0));
2606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pixel[2] = static_cast<uint8>(
2607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          pixel[2] * (kHighlightColorR / 255.0));
2608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine::SelectionChangeInvalidator::SelectionChangeInvalidator(
2613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PDFiumEngine* engine) : engine_(engine) {
2614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  previous_origin_ = engine_->GetVisibleRect().point();
2615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetVisibleSelectionsScreenRects(&old_selections_);
2616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine::SelectionChangeInvalidator::~SelectionChangeInvalidator() {
2619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Offset the old selections if the document scrolled since we recorded them.
2620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Point offset = previous_origin_ - engine_->GetVisibleRect().point();
2621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < old_selections_.size(); ++i)
2622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    old_selections_[i].Offset(offset);
2623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<pp::Rect> new_selections;
2625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetVisibleSelectionsScreenRects(&new_selections);
2626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < new_selections.size(); ++i) {
2627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t j = 0; j < old_selections_.size(); ++j) {
2628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (new_selections[i] == old_selections_[j]) {
2629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Rectangle was selected before and after, so no need to invalidate it.
2630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Mark the rectangles by setting them to empty.
2631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new_selections[i] = old_selections_[j] = pp::Rect();
2632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
2633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < old_selections_.size(); ++i) {
2637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!old_selections_[i].IsEmpty())
2638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      engine_->client_->Invalidate(old_selections_[i]);
2639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < new_selections.size(); ++i) {
2641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!new_selections[i].IsEmpty())
2642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      engine_->client_->Invalidate(new_selections[i]);
2643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine_->OnSelectionChanged();
2645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void
2648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFiumEngine::SelectionChangeInvalidator::GetVisibleSelectionsScreenRects(
2649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<pp::Rect>* rects) {
2650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect visible_rect = engine_->GetVisibleRect();
2651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < engine_->selection_.size(); ++i) {
2652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int page_index = engine_->selection_[i].page_index();
2653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!engine_->IsPageVisible(page_index))
2654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;  // This selection is on a page that's not currently visible.
2655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<pp::Rect> selection_rects =
2657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        engine_->selection_[i].GetScreenRects(
2658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            visible_rect.point(),
2659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            engine_->current_zoom_,
2660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            engine_->current_rotation_);
2661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rects->insert(rects->end(), selection_rects.begin(), selection_rects.end());
2662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::DeviceToPage(int page_index,
2666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                float device_x,
2667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                float device_y,
2668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                double* page_x,
2669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                double* page_y) {
2670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *page_x = *page_y = 0;
2671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int temp_x = static_cast<int>((device_x + position_.x())/ current_zoom_ -
2672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().x());
2673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int temp_y = static_cast<int>((device_y + position_.y())/ current_zoom_ -
2674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().y());
2675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DeviceToPage(
2676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->GetPage(), 0, 0,
2677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pages_[page_index]->rect().width(),  pages_[page_index]->rect().height(),
2678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_rotation_, temp_x, temp_y, page_x, page_y);
2679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::GetVisiblePageIndex(FPDF_PAGE page) {
2682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < visible_pages_.size(); ++i) {
2683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (pages_[visible_pages_[i]]->GetPage() == page)
2684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return visible_pages_[i];
2685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return -1;
2687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::SetCurrentPage(int index) {
2690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (index == most_visible_page_ || !form_)
2691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (most_visible_page_ != -1 && called_do_document_action_) {
2693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE old_page = pages_[most_visible_page_]->GetPage();
2694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FORM_DoPageAAction(old_page, form_, FPDFPAGE_AACTION_CLOSE);
2695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  most_visible_page_ = index;
2697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_LINUX)
2698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    g_last_instance_id = client_->GetPluginInstance()->pp_instance();
2699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
2700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (most_visible_page_ != -1 && called_do_document_action_) {
2701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE new_page = pages_[most_visible_page_]->GetPage();
2702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FORM_DoPageAAction(new_page, form_, FPDFPAGE_AACTION_OPEN);
2703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::TransformPDFPageForPrinting(
2707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_PAGE page,
2708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PP_PrintSettings_Dev& print_settings) {
2709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Get the source page width and height in points.
2710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const double src_page_width = FPDF_GetPageWidth(page);
2711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const double src_page_height = FPDF_GetPageHeight(page);
2712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int src_page_rotation = FPDFPage_GetRotation(page);
2714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const bool fit_to_page = print_settings.print_scaling_option ==
2715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
2716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Size page_size(print_settings.paper_size);
2718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect content_rect(print_settings.printable_area);
2719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const bool rotated = (src_page_rotation % 2 == 1);
2720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetPageSizeAndContentRect(rotated,
2721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            src_page_width > src_page_height,
2722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            &page_size,
2723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            &content_rect);
2724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Compute the screen page width and height in points.
2726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int actual_page_width =
2727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rotated ? page_size.height() : page_size.width();
2728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int actual_page_height =
2729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rotated ? page_size.width() : page_size.height();
2730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const double scale_factor = CalculateScaleFactor(fit_to_page, content_rect,
2732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                   src_page_width,
2733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                   src_page_height, rotated);
2734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Calculate positions for the clip box.
2736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ClipBox source_clip_box;
2737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CalculateClipBoxBoundary(page, scale_factor, rotated, &source_clip_box);
2738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Calculate the translation offset values.
2740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double offset_x = 0;
2741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  double offset_y = 0;
2742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (fit_to_page) {
2743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CalculateScaledClipBoxOffset(content_rect, source_clip_box, &offset_x,
2744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 &offset_y);
2745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
2746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CalculateNonScaledClipBoxOffset(content_rect, src_page_rotation,
2747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    actual_page_width, actual_page_height,
2748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    source_clip_box, &offset_x, &offset_y);
2749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reset the media box and crop box. When the page has crop box and media box,
2752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the plugin will display the crop box contents and not the entire media box.
2753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the pages have different crop box values, the plugin will display a
2754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // document of multiple page sizes. To give better user experience, we
2755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // decided to have same crop box and media box values. Hence, the user will
2756cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // see a list of uniform pages.
2757cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_SetMediaBox(page, 0, 0, page_size.width(), page_size.height());
2758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_SetCropBox(page, 0, 0, page_size.width(), page_size.height());
2759cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Transformation is not required, return. Do this check only after updating
2761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the media box and crop box. For more detailed information, please refer to
2762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the comment block right before FPDF_SetMediaBox and FPDF_GetMediaBox calls.
2763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (scale_factor == 1.0 && offset_x == 0 && offset_y == 0)
2764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // All the positions have been calculated, now manipulate the PDF.
2768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FS_MATRIX matrix = {static_cast<float>(scale_factor),
2769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      0,
2770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      0,
2771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      static_cast<float>(scale_factor),
2772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      static_cast<float>(offset_x),
2773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      static_cast<float>(offset_y)};
2774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FS_RECTF cliprect = {static_cast<float>(source_clip_box.left+offset_x),
2775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       static_cast<float>(source_clip_box.top+offset_y),
2776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       static_cast<float>(source_clip_box.right+offset_x),
2777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       static_cast<float>(source_clip_box.bottom+offset_y)};
2778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_TransFormWithClip(page, &matrix, &cliprect);
2779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor,
2780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           offset_x, offset_y);
2781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::DrawPageShadow(const pp::Rect& page_rc,
2784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const pp::Rect& shadow_rc,
2785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const pp::Rect& clip_rc,
2786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  pp::ImageData* image_data) {
2787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect page_rect(page_rc);
2788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_rect.Offset(page_offset_);
2789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect shadow_rect(shadow_rc);
2791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  shadow_rect.Offset(page_offset_);
2792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect clip_rect(clip_rc);
2794cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  clip_rect.Offset(page_offset_);
2795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Page drop shadow parameters.
2797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const double factor = 0.5;
2798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const uint32 background = (kBackgroundColorA << 24) |
2799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            (kBackgroundColorR << 16) |
2800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            (kBackgroundColorG << 8) |
2801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            kBackgroundColorB;
2802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 depth = std::max(
2803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::max(page_rect.x() - shadow_rect.x(),
2804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               page_rect.y() - shadow_rect.y()),
2805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::max(shadow_rect.right() - page_rect.right(),
2806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               shadow_rect.bottom() - page_rect.bottom()));
2807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  depth = static_cast<uint32>(depth * 1.5) + 1;
2808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We need to check depth only to verify our copy of shadow matrix is correct.
2810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!page_shadow_.get() || page_shadow_->depth() != depth)
2811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    page_shadow_.reset(new ShadowMatrix(depth, factor, background));
2812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!image_data->is_null());
2814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DrawShadow(image_data, shadow_rect, page_rect, clip_rect, *page_shadow_);
2815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::GetRegion(const pp::Point& location,
2818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             pp::ImageData* image_data,
2819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             void** region,
2820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int* stride) const {
2821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (image_data->is_null()) {
2822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(plugin_size_.IsEmpty());
2823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *stride = 0;
2824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *region = NULL;
2825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  char* buffer = static_cast<char*>(image_data->data());
2828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *stride = image_data->stride();
2829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Point offset_location = location + page_offset_;
2831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO: update this when we support BIDI and scrollbars can be on the left.
2832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!buffer ||
2833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !pp::Rect(page_offset_, plugin_size_).Contains(offset_location)) {
2834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *region = NULL;
2835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  buffer += location.y() * (*stride);
2839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  buffer += (location.x() + page_offset_.x()) * 4;
2840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *region = buffer;
2841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::OnSelectionChanged() {
2844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasPermission(PDFEngine::PERMISSION_COPY))
2845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::PDF::SetSelectedText(GetPluginInstance(), GetSelectedText().c_str());
2846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_Invalidate(FPDF_FORMFILLINFO* param,
2849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   FPDF_PAGE page,
2850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   double left,
2851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   double top,
2852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   double right,
2853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   double bottom) {
2854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = engine->GetVisiblePageIndex(page);
2856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_index == -1) {
2857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // This can sometime happen when the page is closed because it went off
2858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // screen, and PDFium invalidates the control as it's being deleted.
2859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect rect = engine->pages_[page_index]->PageToScreen(
2863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
2864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bottom, engine->current_rotation_);
2865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->Invalidate(rect);
2866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2867cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_OutputSelectedRect(FPDF_FORMFILLINFO* param,
2869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           FPDF_PAGE page,
2870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           double left,
2871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           double top,
2872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           double right,
2873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           double bottom) {
2874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_index = engine->GetVisiblePageIndex(page);
2876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_index == -1) {
2877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
2878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect rect = engine->pages_[page_index]->PageToScreen(
2881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
2882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bottom, engine->current_rotation_);
2883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->form_highlights_.push_back(rect);
2884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_SetCursor(FPDF_FORMFILLINFO* param, int cursor_type) {
2887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We don't need this since it's not enough to change the cursor in all
2888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // scenarios.  Instead, we check which form field we're under in OnMouseMove.
2889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_SetTimer(FPDF_FORMFILLINFO* param,
2892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                int elapse,
2893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                TimerCallback timer_func) {
2894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->timers_[++engine->next_timer_id_] =
2896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::pair<int, TimerCallback>(elapse, timer_func);
2897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->ScheduleCallback(engine->next_timer_id_, elapse);
2898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return engine->next_timer_id_;
2899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_KillTimer(FPDF_FORMFILLINFO* param, int timer_id) {
2902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->timers_.erase(timer_id);
2904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_SYSTEMTIME PDFiumEngine::Form_GetLocalTime(FPDF_FORMFILLINFO* param) {
2907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Time time = base::Time::Now();
2908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Time::Exploded exploded;
2909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  time.LocalExplode(&exploded);
2910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_SYSTEMTIME rv;
2912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wYear = exploded.year;
2913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wMonth = exploded.month;
2914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wDayOfWeek = exploded.day_of_week;
2915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wDay = exploded.day_of_month;
2916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wHour = exploded.hour;
2917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wMinute = exploded.minute;
2918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wSecond = exploded.second;
2919cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rv.wMilliseconds = exploded.millisecond;
2920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv;
2921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_OnChange(FPDF_FORMFILLINFO* param) {
2924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Don't care about.
2925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_PAGE PDFiumEngine::Form_GetPage(FPDF_FORMFILLINFO* param,
2928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     FPDF_DOCUMENT document,
2929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int page_index) {
2930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_index < 0 || page_index >= static_cast<int>(engine->pages_.size()))
2932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
2933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return engine->pages_[page_index]->GetPage();
2934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_PAGE PDFiumEngine::Form_GetCurrentPage(FPDF_FORMFILLINFO* param,
2937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            FPDF_DOCUMENT document) {
2938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(jam): find out what this is used for.
2939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int index = engine->last_page_mouse_down_;
2941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (index == -1) {
2942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    index = engine->GetMostVisiblePage();
2943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (index == -1) {
2944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
2945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return NULL;
2946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
2947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return engine->pages_[index]->GetPage();
2950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_GetRotation(FPDF_FORMFILLINFO* param, FPDF_PAGE page) {
2953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return 0;
2954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_ExecuteNamedAction(FPDF_FORMFILLINFO* param,
2957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           FPDF_BYTESTRING named_action) {
2958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
2959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string action(named_action);
2960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (action == "Print") {
2961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->Print();
2962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int index = engine->last_page_mouse_down_;
2966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /* Don't try to calculate the most visible page if we don't have a left click
2967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     before this event (this code originally copied Form_GetCurrentPage which of
2968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     course needs to do that and which doesn't have recursion). This can end up
2969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     causing infinite recursion. See http://crbug.com/240413 for more
2970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     information. Either way, it's not necessary for the spec'd list of named
2971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     actions.
2972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (index == -1)
2973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    index = engine->GetMostVisiblePage();
2974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  */
2975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (index == -1)
2976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
2977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This is the only list of named actions per the spec (see 12.6.4.11). Adobe
2979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reader supports more, like FitWidth, but since they're not part of the spec
2980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // and we haven't got bugs about them, no need to now.
2981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (action == "NextPage") {
2982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->ScrollToPage(index + 1);
2983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (action == "PrevPage") {
2984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->ScrollToPage(index - 1);
2985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (action == "FirstPage") {
2986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->ScrollToPage(0);
2987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (action == "LastPage") {
2988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->ScrollToPage(engine->pages_.size() - 1);
2989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_SetTextFieldFocus(FPDF_FORMFILLINFO* param,
2993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          FPDF_WIDESTRING value,
2994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          FPDF_DWORD valueLen,
2995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          FPDF_BOOL is_focus) {
2996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do nothing for now.
2997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(gene): use this signal to trigger OSK.
2998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
2999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_DoURIAction(FPDF_FORMFILLINFO* param,
3001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    FPDF_BYTESTRING uri) {
3002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->NavigateTo(std::string(uri), false);
3004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_DoGoToAction(FPDF_FORMFILLINFO* param,
3007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int page_index,
3008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int zoom_mode,
3009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     float* position_array,
3010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     int size_of_array) {
3011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->ScrollToPage(page_index);
3013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_Alert(IPDF_JSPLATFORM* param,
3016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING message,
3017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING title,
3018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int type,
3019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int icon) {
3020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // See fpdfformfill.h for these values.
3021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  enum AlertType {
3022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_TYPE_OK = 0,
3023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_TYPE_OK_CANCEL,
3024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_TYPE_YES_ON,
3025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_TYPE_YES_NO_CANCEL
3026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
3027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  enum AlertResult {
3029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_RESULT_OK = 1,
3030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_RESULT_CANCEL,
3031cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_RESULT_NO,
3032cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ALERT_RESULT_YES
3033cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
3034cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3035cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3036cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string message_str =
3037cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
3038cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (type == ALERT_TYPE_OK) {
3039cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    engine->client_->Alert(message_str);
3040cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return ALERT_RESULT_OK;
3041cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool rv = engine->client_->Confirm(message_str);
3044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (type == ALERT_TYPE_OK_CANCEL)
3045cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return rv ? ALERT_RESULT_OK : ALERT_RESULT_CANCEL;
3046cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv ? ALERT_RESULT_YES : ALERT_RESULT_NO;
3047cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3048cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_Beep(IPDF_JSPLATFORM* param, int type) {
3050cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Beeps are annoying, and not possible using javascript, so ignore for now.
3051cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3052cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3053cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_Response(IPDF_JSPLATFORM* param,
3054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                FPDF_WIDESTRING question,
3055cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                FPDF_WIDESTRING title,
3056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                FPDF_WIDESTRING default_response,
3057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                FPDF_WIDESTRING label,
3058cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                FPDF_BOOL password,
3059cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                void* response,
3060cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                int length) {
3061cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string question_str = base::UTF16ToUTF8(
3062cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reinterpret_cast<const base::char16*>(question));
3063cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string default_str = base::UTF16ToUTF8(
3064cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reinterpret_cast<const base::char16*>(default_response));
3065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string rv = engine->client_->Prompt(question_str, default_str);
3068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 rv_16 = base::UTF8ToUTF16(rv);
3069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rv_bytes = rv_16.size() * sizeof(base::char16);
3070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (response && rv_bytes <= length)
3071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    memcpy(response, rv_16.c_str(), rv_bytes);
3072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv_bytes;
3073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_GetFilePath(IPDF_JSPLATFORM* param,
3076cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   void* file_path,
3077cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   int length) {
3078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string rv = engine->client_->GetURL();
3080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (file_path && rv.size() <= static_cast<size_t>(length))
3081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    memcpy(file_path, rv.c_str(), rv.size());
3082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rv.size();
3083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_Mail(IPDF_JSPLATFORM* param,
3086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             void* mail_data,
3087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int length,
3088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_BOOL ui,
3089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING to,
3090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING subject,
3091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING cc,
3092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING bcc,
3093cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             FPDF_WIDESTRING message) {
3094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(length == 0);  // Don't handle attachments; no way with mailto.
3095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string to_str =
3096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(to));
3097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string cc_str =
3098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(cc));
3099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string bcc_str =
3100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(bcc));
3101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string subject_str =
3102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(subject));
3103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string message_str =
3104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
3105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
3108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_Print(IPDF_JSPLATFORM* param,
3111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL ui,
3112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              int start,
3113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              int end,
3114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL silent,
3115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL shrink_to_fit,
3116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL print_as_image,
3117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL reverse,
3118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              FPDF_BOOL annotations) {
3119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No way to pass the extra information to the print dialog using JavaScript.
3120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Just opening it is fine for now.
3121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->Print();
3123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_SubmitForm(IPDF_JSPLATFORM* param,
3126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   void* form_data,
3127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   int length,
3128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   FPDF_WIDESTRING url) {
3129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string url_str =
3130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(url));
3131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->SubmitForm(url_str, form_data, length);
3133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PDFiumEngine::Form_GotoPage(IPDF_JSPLATFORM* param,
3136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 int page_number) {
3137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  engine->client_->ScrollToPage(page_number);
3139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int PDFiumEngine::Form_Browse(IPDF_JSPLATFORM* param,
3142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              void* file_path,
3143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              int length) {
3144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string path = engine->client_->ShowFileSelectionDialog();
3146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (path.size() + 1 <= static_cast<size_t>(length))
3147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    memcpy(file_path, &path[0], path.size() + 1);
3148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return path.size() + 1;
3149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FPDF_BOOL PDFiumEngine::Pause_NeedToPauseNow(IFSDK_PAUSE* param) {
3152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
3153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (base::Time::Now() - engine->last_progressive_start_time_).
3154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      InMilliseconds() > engine->progressive_paint_timeout_;
3155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScopedUnsupportedFeature::ScopedUnsupportedFeature(PDFiumEngine* engine)
3158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : engine_(engine), old_engine_(g_engine_for_unsupported) {
3159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_engine_for_unsupported = engine_;
3160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScopedUnsupportedFeature::~ScopedUnsupportedFeature() {
3163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_engine_for_unsupported = old_engine_;
3164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PDFEngineExports* PDFEngineExports::Create() {
3167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new PDFiumEngineExports;
3168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
3171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int CalculatePosition(FPDF_PAGE page,
3173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      const PDFiumEngineExports::RenderingSettings& settings,
3174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      pp::Rect* dest) {
3175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_width = static_cast<int>(
3176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_GetPageWidth(page) * settings.dpi_x / kPointsPerInch);
3177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_height = static_cast<int>(
3178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_GetPageHeight(page) * settings.dpi_y / kPointsPerInch);
3179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Start by assuming that we will draw exactly to the bounds rect
3181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // specified.
3182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *dest = settings.bounds;
3183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rotate = 0;  // normal orientation.
3185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Auto-rotate landscape pages to print correctly.
3187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (settings.autorotate &&
3188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (dest->width() > dest->height()) != (page_width > page_height)) {
3189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rotate = 1;  // 90 degrees clockwise.
3190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::swap(page_width, page_height);
3191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // See if we need to scale the output
3194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool scale_to_bounds = false;
3195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (settings.fit_to_bounds &&
3196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ((page_width > dest->width()) || (page_height > dest->height()))) {
3197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scale_to_bounds = true;
3198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (settings.stretch_to_bounds &&
3199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             ((page_width < dest->width()) || (page_height < dest->height()))) {
3200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scale_to_bounds = true;
3201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (scale_to_bounds) {
3204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // If we need to maintain aspect ratio, calculate the actual width and
3205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // height.
3206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (settings.keep_aspect_ratio) {
3207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      double scale_factor_x = page_width;
3208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scale_factor_x /= dest->width();
3209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      double scale_factor_y = page_height;
3210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scale_factor_y /= dest->height();
3211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (scale_factor_x > scale_factor_y) {
3212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        dest->set_height(page_height / scale_factor_x);
3213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
3214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        dest->set_width(page_width / scale_factor_y);
3215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
3216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
3217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
3218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We are not scaling to bounds. Draw in the actual page size. If the
3219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // actual page size is larger than the bounds, the output will be
3220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // clipped.
3221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    dest->set_width(page_width);
3222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    dest->set_height(page_height);
3223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (settings.center_in_bounds) {
3226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pp::Point offset((settings.bounds.width() - dest->width()) / 2,
3227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     (settings.bounds.height() - dest->height()) / 2);
3228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    dest->Offset(offset);
3229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return rotate;
3231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
3234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
3236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
3237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            int buffer_size,
3238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            int page_number,
3239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            const RenderingSettings& settings,
3240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                            HDC dc) {
3241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, NULL);
3242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc)
3243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
3244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
3245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!page) {
3246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(doc);
3247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
3248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RenderingSettings new_settings = settings;
3250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // calculate the page size
3251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (new_settings.dpi_x == -1)
3252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    new_settings.dpi_x = GetDeviceCaps(dc, LOGPIXELSX);
3253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (new_settings.dpi_y == -1)
3254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    new_settings.dpi_y = GetDeviceCaps(dc, LOGPIXELSY);
3255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dest;
3257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rotate = CalculatePosition(page, new_settings, &dest);
3258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int save_state = SaveDC(dc);
3260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The caller wanted all drawing to happen within the bounds specified.
3261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Based on scale calculations, our destination rect might be larger
3262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // than the bounds. Set the clip rect to the bounds.
3263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IntersectClipRect(dc, settings.bounds.x(), settings.bounds.y(),
3264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    settings.bounds.x() + settings.bounds.width(),
3265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    settings.bounds.y() + settings.bounds.height());
3266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // A temporary hack. PDFs generated by Cairo (used by Chrome OS to generate
3268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // a PDF output from a webpage) result in very large metafiles and the
3269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // rendering using FPDF_RenderPage is incorrect. In this case, render as a
3270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // bitmap. Note that this code does not kick in for PDFs printed from Chrome
3271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // because in that case we create a temp PDF first before printing and this
3272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // temp PDF does not have a creator string that starts with "cairo".
3273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 creator;
3274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t buffer_bytes = FPDF_GetMetaText(doc, "Creator", NULL, 0);
3275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (buffer_bytes > 1) {
3276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_GetMetaText(doc, "Creator", WriteInto(&creator, buffer_bytes),
3277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     buffer_bytes);
3278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool use_bitmap = false;
3280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (StartsWith(creator, L"cairo", false))
3281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    use_bitmap = true;
3282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Another temporary hack. Some PDFs seems to render very slowly if
3284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // FPDF_RenderPage is directly used on a printer DC. I suspect it is
3285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // because of the code to talk Postscript directly to the printer if
3286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the printer supports this. Need to discuss this with PDFium. For now,
3287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // render to a bitmap and then blit the bitmap to the DC if we have been
3288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // supplied a printer DC.
3289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int device_type = GetDeviceCaps(dc, TECHNOLOGY);
3290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (use_bitmap ||
3291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (device_type == DT_RASPRINTER) || (device_type == DT_PLOTTER)) {
3292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_BITMAP bitmap = FPDFBitmap_Create(dest.width(), dest.height(),
3293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           FPDFBitmap_BGRx);
3294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Clear the bitmap
3295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_FillRect(bitmap, 0, 0, dest.width(), dest.height(), 255, 255,
3296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        255, 255);
3297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPageBitmap(
3298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        bitmap, page, 0, 0, dest.width(), dest.height(), rotate,
3299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
3300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int stride = FPDFBitmap_GetStride(bitmap);
3301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    BITMAPINFO bmi;
3302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    memset(&bmi, 0, sizeof(bmi));
3303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biWidth = dest.width();
3305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biHeight = -dest.height();  // top-down image
3306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biPlanes = 1;
3307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biBitCount = 32;
3308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biCompression = BI_RGB;
3309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bmi.bmiHeader.biSizeImage = stride * dest.height();
3310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    StretchDIBits(dc, dest.x(), dest.y(), dest.width(), dest.height(),
3311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  0, 0, dest.width(), dest.height(),
3312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  FPDFBitmap_GetBuffer(bitmap), &bmi, DIB_RGB_COLORS, SRCCOPY);
3313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDFBitmap_Destroy(bitmap);
3314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
3315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_RenderPage(dc, page, dest.x(), dest.y(), dest.width(), dest.height(),
3316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    rotate, FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
3317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RestoreDC(dc, save_state);
3319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_ClosePage(page);
3320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CloseDocument(doc);
3321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
3322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // OS_WIN
3324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngineExports::RenderPDFPageToBitmap(
3326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const void* pdf_buffer,
3327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int pdf_buffer_size,
3328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int page_number,
3329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const RenderingSettings& settings,
3330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    void* bitmap_buffer) {
3331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL);
3332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc)
3333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
3334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
3335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!page) {
3336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FPDF_CloseDocument(doc);
3337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
3338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::Rect dest;
3341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rotate = CalculatePosition(page, settings, &dest);
3342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_BITMAP bitmap =
3344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDFBitmap_CreateEx(settings.bounds.width(), settings.bounds.height(),
3345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          FPDFBitmap_BGRA, bitmap_buffer,
3346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          settings.bounds.width() * 4);
3347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clear the bitmap
3348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_FillRect(bitmap, 0, 0, settings.bounds.width(),
3349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      settings.bounds.height(), 255, 255, 255, 255);
3350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Shift top-left corner of bounds to (0, 0) if it's not there.
3351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dest.set_point(dest.point() - settings.bounds.point());
3352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_RenderPageBitmap(
3353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      bitmap, page, dest.x(), dest.y(), dest.width(), dest.height(), rotate,
3354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
3355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDFBitmap_Destroy(bitmap);
3356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_ClosePage(page);
3357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CloseDocument(doc);
3358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
3359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PDFiumEngineExports::GetPDFDocInfo(const void* pdf_buffer,
3362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        int buffer_size,
3363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        int* page_count,
3364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        double* max_page_width) {
3365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, NULL);
3366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!doc)
3367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
3368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int page_count_local = FPDF_GetPageCount(doc);
3369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (page_count) {
3370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *page_count = page_count_local;
3371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (max_page_width) {
3373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *max_page_width = 0;
3374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int page_number = 0; page_number < page_count_local; page_number++) {
3375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      double page_width = 0;
3376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      double page_height = 0;
3377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FPDF_GetPageSizeByIndex(doc, page_number, &page_width, &page_height);
3378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (page_width > *max_page_width) {
3379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        *max_page_width = page_width;
3380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
3381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
3382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FPDF_CloseDocument(doc);
3384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
3385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chrome_pdf
3388