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