| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "pdf/pdfium/pdfium_engine.h" | 5 #include "pdf/pdfium/pdfium_engine.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/i18n/icu_encoding_detection.h" | 9 #include "base/i18n/icu_encoding_detection.h" |
| 10 #include "base/i18n/icu_string_conversions.h" | 10 #include "base/i18n/icu_string_conversions.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "ppapi/c/private/ppb_pdf.h" | 29 #include "ppapi/c/private/ppb_pdf.h" |
| 30 #include "ppapi/cpp/dev/memory_dev.h" | 30 #include "ppapi/cpp/dev/memory_dev.h" |
| 31 #include "ppapi/cpp/input_event.h" | 31 #include "ppapi/cpp/input_event.h" |
| 32 #include "ppapi/cpp/instance.h" | 32 #include "ppapi/cpp/instance.h" |
| 33 #include "ppapi/cpp/module.h" | 33 #include "ppapi/cpp/module.h" |
| 34 #include "ppapi/cpp/private/pdf.h" | 34 #include "ppapi/cpp/private/pdf.h" |
| 35 #include "ppapi/cpp/trusted/browser_font_trusted.h" | 35 #include "ppapi/cpp/trusted/browser_font_trusted.h" |
| 36 #include "ppapi/cpp/url_response_info.h" | 36 #include "ppapi/cpp/url_response_info.h" |
| 37 #include "ppapi/cpp/var.h" | 37 #include "ppapi/cpp/var.h" |
| 38 #include "ppapi/cpp/var_dictionary.h" | 38 #include "ppapi/cpp/var_dictionary.h" |
| 39 #include "printing/pdf_transform.h" |
| 39 #include "printing/units.h" | 40 #include "printing/units.h" |
| 40 #include "third_party/pdfium/public/fpdf_edit.h" | 41 #include "third_party/pdfium/public/fpdf_edit.h" |
| 41 #include "third_party/pdfium/public/fpdf_ext.h" | 42 #include "third_party/pdfium/public/fpdf_ext.h" |
| 42 #include "third_party/pdfium/public/fpdf_flatten.h" | 43 #include "third_party/pdfium/public/fpdf_flatten.h" |
| 43 #include "third_party/pdfium/public/fpdf_ppo.h" | 44 #include "third_party/pdfium/public/fpdf_ppo.h" |
| 44 #include "third_party/pdfium/public/fpdf_save.h" | 45 #include "third_party/pdfium/public/fpdf_save.h" |
| 45 #include "third_party/pdfium/public/fpdf_searchex.h" | 46 #include "third_party/pdfium/public/fpdf_searchex.h" |
| 46 #include "third_party/pdfium/public/fpdf_sysfontinfo.h" | 47 #include "third_party/pdfium/public/fpdf_sysfontinfo.h" |
| 47 #include "third_party/pdfium/public/fpdf_transformpage.h" | 48 #include "third_party/pdfium/public/fpdf_transformpage.h" |
| 48 #include "ui/events/keycodes/keyboard_codes.h" | 49 #include "ui/events/keycodes/keyboard_codes.h" |
| 50 #include "ui/gfx/geometry/rect.h" |
| 49 #include "v8/include/v8.h" | 51 #include "v8/include/v8.h" |
| 50 | 52 |
| 51 using printing::ConvertUnit; | 53 using printing::ConvertUnit; |
| 52 using printing::ConvertUnitDouble; | 54 using printing::ConvertUnitDouble; |
| 53 using printing::kPointsPerInch; | 55 using printing::kPointsPerInch; |
| 54 using printing::kPixelsPerInch; | 56 using printing::kPixelsPerInch; |
| 55 | 57 |
| 56 namespace chrome_pdf { | 58 namespace chrome_pdf { |
| 57 | 59 |
| 58 namespace { | 60 namespace { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 page_numbers.push_back(page_number); | 110 page_numbers.push_back(page_number); |
| 109 } | 111 } |
| 110 } | 112 } |
| 111 return page_numbers; | 113 return page_numbers; |
| 112 } | 114 } |
| 113 | 115 |
| 114 #if defined(OS_LINUX) | 116 #if defined(OS_LINUX) |
| 115 | 117 |
| 116 PP_Instance g_last_instance_id; | 118 PP_Instance g_last_instance_id; |
| 117 | 119 |
| 118 struct PDFFontSubstitution { | |
| 119 const char* pdf_name; | |
| 120 const char* face; | |
| 121 bool bold; | |
| 122 bool italic; | |
| 123 }; | |
| 124 | |
| 125 PP_BrowserFont_Trusted_Weight WeightToBrowserFontTrustedWeight(int weight) { | 120 PP_BrowserFont_Trusted_Weight WeightToBrowserFontTrustedWeight(int weight) { |
| 126 static_assert(PP_BROWSERFONT_TRUSTED_WEIGHT_100 == 0, | 121 static_assert(PP_BROWSERFONT_TRUSTED_WEIGHT_100 == 0, |
| 127 "PP_BrowserFont_Trusted_Weight min"); | 122 "PP_BrowserFont_Trusted_Weight min"); |
| 128 static_assert(PP_BROWSERFONT_TRUSTED_WEIGHT_900 == 8, | 123 static_assert(PP_BROWSERFONT_TRUSTED_WEIGHT_900 == 8, |
| 129 "PP_BrowserFont_Trusted_Weight max"); | 124 "PP_BrowserFont_Trusted_Weight max"); |
| 130 const int kMinimumWeight = 100; | 125 const int kMinimumWeight = 100; |
| 131 const int kMaximumWeight = 900; | 126 const int kMaximumWeight = 900; |
| 132 int normalized_weight = | 127 int normalized_weight = |
| 133 std::min(std::max(weight, kMinimumWeight), kMaximumWeight); | 128 std::min(std::max(weight, kMinimumWeight), kMaximumWeight); |
| 134 normalized_weight = (normalized_weight / 100) - 1; | 129 normalized_weight = (normalized_weight / 100) - 1; |
| 135 return static_cast<PP_BrowserFont_Trusted_Weight>(normalized_weight); | 130 return static_cast<PP_BrowserFont_Trusted_Weight>(normalized_weight); |
| 136 } | 131 } |
| 137 | 132 |
| 138 // This list is for CPWL_FontMap::GetDefaultFontByCharset(). | 133 // This list is for CPWL_FontMap::GetDefaultFontByCharset(). |
| 139 // We pretend to have these font natively and let the browser (or underlying | 134 // We pretend to have these font natively and let the browser (or underlying |
| 140 // fontconfig) to pick the proper font on the system. | 135 // fontconfig) to pick the proper font on the system. |
| 141 void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) { | 136 void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) { |
| 142 FPDF_AddInstalledFont(mapper, "Arial", FXFONT_DEFAULT_CHARSET); | 137 FPDF_AddInstalledFont(mapper, "Arial", FXFONT_DEFAULT_CHARSET); |
| 143 | 138 |
| 144 const FPDF_CharsetFontMap* font_map = FPDF_GetDefaultTTFMap(); | 139 const FPDF_CharsetFontMap* font_map = FPDF_GetDefaultTTFMap(); |
| 145 for (; font_map->charset != -1; ++font_map) { | 140 for (; font_map->charset != -1; ++font_map) { |
| 146 FPDF_AddInstalledFont(mapper, font_map->fontname, font_map->charset); | 141 FPDF_AddInstalledFont(mapper, font_map->fontname, font_map->charset); |
| 147 } | 142 } |
| 148 } | 143 } |
| 149 | 144 |
| 150 const PDFFontSubstitution PDFFontSubstitutions[] = { | 145 void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic, |
| 146 int charset, int pitch_family, const char* face, int* exact) { |
| 147 // Do not attempt to map fonts if pepper is not initialized (for privet local |
| 148 // printing). |
| 149 // TODO(noamsml): Real font substitution (http://crbug.com/391978) |
| 150 if (!pp::Module::Get()) |
| 151 return NULL; |
| 152 |
| 153 pp::BrowserFontDescription description; |
| 154 |
| 155 // Pretend the system does not have the Symbol font to force a fallback to |
| 156 // the built in Symbol font in CFX_FontMapper::FindSubstFont(). |
| 157 if (strcmp(face, "Symbol") == 0) |
| 158 return NULL; |
| 159 |
| 160 if (pitch_family & FXFONT_FF_FIXEDPITCH) { |
| 161 description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE); |
| 162 } else if (pitch_family & FXFONT_FF_ROMAN) { |
| 163 description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_SERIF); |
| 164 } |
| 165 |
| 166 static const struct { |
| 167 const char* pdf_name; |
| 168 const char* face; |
| 169 bool bold; |
| 170 bool italic; |
| 171 } kPdfFontSubstitutions[] = { |
| 151 {"Courier", "Courier New", false, false}, | 172 {"Courier", "Courier New", false, false}, |
| 152 {"Courier-Bold", "Courier New", true, false}, | 173 {"Courier-Bold", "Courier New", true, false}, |
| 153 {"Courier-BoldOblique", "Courier New", true, true}, | 174 {"Courier-BoldOblique", "Courier New", true, true}, |
| 154 {"Courier-Oblique", "Courier New", false, true}, | 175 {"Courier-Oblique", "Courier New", false, true}, |
| 155 {"Helvetica", "Arial", false, false}, | 176 {"Helvetica", "Arial", false, false}, |
| 156 {"Helvetica-Bold", "Arial", true, false}, | 177 {"Helvetica-Bold", "Arial", true, false}, |
| 157 {"Helvetica-BoldOblique", "Arial", true, true}, | 178 {"Helvetica-BoldOblique", "Arial", true, true}, |
| 158 {"Helvetica-Oblique", "Arial", false, true}, | 179 {"Helvetica-Oblique", "Arial", false, true}, |
| 159 {"Times-Roman", "Times New Roman", false, false}, | 180 {"Times-Roman", "Times New Roman", false, false}, |
| 160 {"Times-Bold", "Times New Roman", true, false}, | 181 {"Times-Bold", "Times New Roman", true, false}, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 176 "MS PGothic", false, false}, | 197 "MS PGothic", false, false}, |
| 177 // MS Gothic in Shift_JIS encoding. | 198 // MS Gothic in Shift_JIS encoding. |
| 178 {"\x82\x6C\x82\x72\x83\x53\x83\x56\x83\x62\x83\x4E", | 199 {"\x82\x6C\x82\x72\x83\x53\x83\x56\x83\x62\x83\x4E", |
| 179 "MS Gothic", false, false}, | 200 "MS Gothic", false, false}, |
| 180 // MS PMincho in Shift_JIS encoding. | 201 // MS PMincho in Shift_JIS encoding. |
| 181 {"\x82\x6C\x82\x72\x82\x6F\x96\xBE\x92\xA9", | 202 {"\x82\x6C\x82\x72\x82\x6F\x96\xBE\x92\xA9", |
| 182 "MS PMincho", false, false}, | 203 "MS PMincho", false, false}, |
| 183 // MS Mincho in Shift_JIS encoding. | 204 // MS Mincho in Shift_JIS encoding. |
| 184 {"\x82\x6C\x82\x72\x96\xBE\x92\xA9", | 205 {"\x82\x6C\x82\x72\x96\xBE\x92\xA9", |
| 185 "MS Mincho", false, false}, | 206 "MS Mincho", false, false}, |
| 186 }; | 207 }; |
| 187 | |
| 188 void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic, | |
| 189 int charset, int pitch_family, const char* face, int* exact) { | |
| 190 // Do not attempt to map fonts if pepper is not initialized (for privet local | |
| 191 // printing). | |
| 192 // TODO(noamsml): Real font substitution (http://crbug.com/391978) | |
| 193 if (!pp::Module::Get()) | |
| 194 return NULL; | |
| 195 | |
| 196 pp::BrowserFontDescription description; | |
| 197 | |
| 198 // Pretend the system does not have the Symbol font to force a fallback to | |
| 199 // the built in Symbol font in CFX_FontMapper::FindSubstFont(). | |
| 200 if (strcmp(face, "Symbol") == 0) | |
| 201 return NULL; | |
| 202 | |
| 203 if (pitch_family & FXFONT_FF_FIXEDPITCH) { | |
| 204 description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE); | |
| 205 } else if (pitch_family & FXFONT_FF_ROMAN) { | |
| 206 description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_SERIF); | |
| 207 } | |
| 208 | 208 |
| 209 // Map from the standard PDF fonts to TrueType font names. | 209 // Map from the standard PDF fonts to TrueType font names. |
| 210 size_t i; | 210 size_t i; |
| 211 for (i = 0; i < arraysize(PDFFontSubstitutions); ++i) { | 211 for (i = 0; i < arraysize(kPdfFontSubstitutions); ++i) { |
| 212 if (strcmp(face, PDFFontSubstitutions[i].pdf_name) == 0) { | 212 if (strcmp(face, kPdfFontSubstitutions[i].pdf_name) == 0) { |
| 213 description.set_face(PDFFontSubstitutions[i].face); | 213 description.set_face(kPdfFontSubstitutions[i].face); |
| 214 if (PDFFontSubstitutions[i].bold) | 214 if (kPdfFontSubstitutions[i].bold) |
| 215 description.set_weight(PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD); | 215 description.set_weight(PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD); |
| 216 if (PDFFontSubstitutions[i].italic) | 216 if (kPdfFontSubstitutions[i].italic) |
| 217 description.set_italic(true); | 217 description.set_italic(true); |
| 218 break; | 218 break; |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 if (i == arraysize(PDFFontSubstitutions)) { | 222 if (i == arraysize(kPdfFontSubstitutions)) { |
| 223 // Convert to UTF-8 before calling set_face(). | 223 // Convert to UTF-8 before calling set_face(). |
| 224 std::string face_utf8; | 224 std::string face_utf8; |
| 225 if (base::IsStringUTF8(face)) { | 225 if (base::IsStringUTF8(face)) { |
| 226 face_utf8 = face; | 226 face_utf8 = face; |
| 227 } else { | 227 } else { |
| 228 std::string encoding; | 228 std::string encoding; |
| 229 if (base::DetectEncoding(face, &encoding)) { | 229 if (base::DetectEncoding(face, &encoding)) { |
| 230 // ConvertToUtf8AndNormalize() clears |face_utf8| on failure. | 230 // ConvertToUtf8AndNormalize() clears |face_utf8| on failure. |
| 231 base::ConvertToUtf8AndNormalize(face, encoding, &face_utf8); | 231 base::ConvertToUtf8AndNormalize(face, encoding, &face_utf8); |
| 232 } | 232 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 | 290 |
| 291 void Unsupported_Handler(UNSUPPORT_INFO*, int type) { | 291 void Unsupported_Handler(UNSUPPORT_INFO*, int type) { |
| 292 if (!g_engine_for_unsupported) { | 292 if (!g_engine_for_unsupported) { |
| 293 NOTREACHED(); | 293 NOTREACHED(); |
| 294 return; | 294 return; |
| 295 } | 295 } |
| 296 | 296 |
| 297 g_engine_for_unsupported->UnsupportedFeature(type); | 297 g_engine_for_unsupported->UnsupportedFeature(type); |
| 298 } | 298 } |
| 299 | 299 |
| 300 UNSUPPORT_INFO g_unsuppored_info = { | 300 UNSUPPORT_INFO g_unsupported_info = { |
| 301 1, | 301 1, |
| 302 Unsupported_Handler | 302 Unsupported_Handler |
| 303 }; | 303 }; |
| 304 | 304 |
| 305 // Set the destination page size and content area in points based on source | 305 // Set the destination page size and content area in points based on source |
| 306 // page rotation and orientation. | 306 // page rotation and orientation. |
| 307 // | 307 // |
| 308 // |rotated| True if source page is rotated 90 degree or 270 degree. | 308 // |rotated| True if source page is rotated 90 degree or 270 degree. |
| 309 // |is_src_page_landscape| is true if the source page orientation is landscape. | 309 // |is_src_page_landscape| is true if the source page orientation is landscape. |
| 310 // |page_size| has the actual destination page size in points. | 310 // |page_size| has the actual destination page size in points. |
| 311 // |content_rect| has the actual destination page printable area values in | 311 // |content_rect| has the actual destination page printable area values in |
| 312 // points. | 312 // points. |
| 313 void SetPageSizeAndContentRect(bool rotated, | 313 void SetPageSizeAndContentRect(bool rotated, |
| 314 bool is_src_page_landscape, | 314 bool is_src_page_landscape, |
| 315 pp::Size* page_size, | 315 pp::Size* page_size, |
| 316 pp::Rect* content_rect) { | 316 pp::Rect* content_rect) { |
| 317 bool is_dst_page_landscape = page_size->width() > page_size->height(); | 317 bool is_dst_page_landscape = page_size->width() > page_size->height(); |
| 318 bool page_orientation_mismatched = is_src_page_landscape != | 318 bool page_orientation_mismatched = is_src_page_landscape != |
| 319 is_dst_page_landscape; | 319 is_dst_page_landscape; |
| 320 bool rotate_dst_page = rotated ^ page_orientation_mismatched; | 320 bool rotate_dst_page = rotated ^ page_orientation_mismatched; |
| 321 if (rotate_dst_page) { | 321 if (rotate_dst_page) { |
| 322 page_size->SetSize(page_size->height(), page_size->width()); | 322 page_size->SetSize(page_size->height(), page_size->width()); |
| 323 content_rect->SetRect(content_rect->y(), content_rect->x(), | 323 content_rect->SetRect(content_rect->y(), content_rect->x(), |
| 324 content_rect->height(), content_rect->width()); | 324 content_rect->height(), content_rect->width()); |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Calculate the scale factor between |content_rect| and a page of size | |
| 329 // |src_width| x |src_height|. | |
| 330 // | |
| 331 // |scale_to_fit| is true, if we need to calculate the scale factor. | |
| 332 // |content_rect| specifies the printable area of the destination page, with | |
| 333 // origin at left-bottom. Values are in points. | |
| 334 // |src_width| specifies the source page width in points. | |
| 335 // |src_height| specifies the source page height in points. | |
| 336 // |rotated| True if source page is rotated 90 degree or 270 degree. | |
| 337 double CalculateScaleFactor(bool scale_to_fit, | |
| 338 const pp::Rect& content_rect, | |
| 339 double src_width, double src_height, bool rotated) { | |
| 340 if (!scale_to_fit || src_width == 0 || src_height == 0) | |
| 341 return 1.0; | |
| 342 | |
| 343 double actual_source_page_width = rotated ? src_height : src_width; | |
| 344 double actual_source_page_height = rotated ? src_width : src_height; | |
| 345 double ratio_x = static_cast<double>(content_rect.width()) / | |
| 346 actual_source_page_width; | |
| 347 double ratio_y = static_cast<double>(content_rect.height()) / | |
| 348 actual_source_page_height; | |
| 349 return std::min(ratio_x, ratio_y); | |
| 350 } | |
| 351 | |
| 352 // A rect struct for use with FPDF bounding box functions. | |
| 353 // Remember with PDFs, origin is bottom-left. | |
| 354 struct ClipBox { | |
| 355 float left; | |
| 356 float right; | |
| 357 float top; | |
| 358 float bottom; | |
| 359 }; | |
| 360 | |
| 361 // Make the default size to be letter size (8.5" X 11"). We are just following | |
| 362 // the PDFium way of handling these corner cases. PDFium always consider | |
| 363 // US-Letter as the default page size. | |
| 364 void SetDefaultClipBox(bool rotated, ClipBox* clip_box) { | |
| 365 const int kDpi = 72; | |
| 366 const float kPaperWidth = 8.5 * kDpi; | |
| 367 const float kPaperHeight = 11 * kDpi; | |
| 368 clip_box->left = 0; | |
| 369 clip_box->bottom = 0; | |
| 370 clip_box->right = rotated ? kPaperHeight : kPaperWidth; | |
| 371 clip_box->top = rotated ? kPaperWidth : kPaperHeight; | |
| 372 } | |
| 373 | |
| 374 // Compute source clip box boundaries based on the crop box / media box of | |
| 375 // source page and scale factor. | |
| 376 // | |
| 377 // |page| Handle to the source page. Returned by FPDF_LoadPage function. | |
| 378 // |scale_factor| specifies the scale factor that should be applied to source | |
| 379 // clip box boundaries. | |
| 380 // |rotated| True if source page is rotated 90 degree or 270 degree. | |
| 381 // |clip_box| out param to hold the computed source clip box values. | |
| 382 void CalculateClipBoxBoundary(FPDF_PAGE page, double scale_factor, bool rotated, | |
| 383 ClipBox* clip_box) { | |
| 384 ClipBox media_box; | |
| 385 if (!FPDFPage_GetMediaBox(page, &media_box.left, &media_box.bottom, | |
| 386 &media_box.right, &media_box.top)) { | |
| 387 SetDefaultClipBox(rotated, &media_box); | |
| 388 } | |
| 389 | |
| 390 ClipBox crop_box; | |
| 391 if (!FPDFPage_GetCropBox(page, &crop_box.left, &crop_box.bottom, | |
| 392 &crop_box.right, &crop_box.top)) { | |
| 393 SetDefaultClipBox(rotated, &crop_box); | |
| 394 } | |
| 395 | |
| 396 // Clip |media_box| to the size of |crop_box|, but ignore |crop_box| if it is | |
| 397 // bigger than |media_box|. | |
| 398 clip_box->left = | |
| 399 (crop_box.left < media_box.left) ? media_box.left : crop_box.left; | |
| 400 clip_box->right = | |
| 401 (crop_box.right > media_box.right) ? media_box.right : crop_box.right; | |
| 402 clip_box->top = (crop_box.top > media_box.top) ? media_box.top : crop_box.top; | |
| 403 clip_box->bottom = | |
| 404 (crop_box.bottom < media_box.bottom) ? media_box.bottom : crop_box.bottom; | |
| 405 | |
| 406 // Finally, scale |clip_box|. | |
| 407 clip_box->left *= scale_factor; | |
| 408 clip_box->right *= scale_factor; | |
| 409 clip_box->bottom *= scale_factor; | |
| 410 clip_box->top *= scale_factor; | |
| 411 } | |
| 412 | |
| 413 // Calculate the clip box translation offset for a page that does need to be | |
| 414 // scaled. All parameters are in points. | |
| 415 // | |
| 416 // |content_rect| specifies the printable area of the destination page, with | |
| 417 // origin at left-bottom. | |
| 418 // |source_clip_box| specifies the source clip box positions, relative to | |
| 419 // origin at left-bottom. | |
| 420 // |offset_x| and |offset_y| will contain the final translation offsets for the | |
| 421 // source clip box, relative to origin at left-bottom. | |
| 422 void CalculateScaledClipBoxOffset(const pp::Rect& content_rect, | |
| 423 const ClipBox& source_clip_box, | |
| 424 double* offset_x, double* offset_y) { | |
| 425 const float clip_box_width = source_clip_box.right - source_clip_box.left; | |
| 426 const float clip_box_height = source_clip_box.top - source_clip_box.bottom; | |
| 427 | |
| 428 // Center the intended clip region to real clip region. | |
| 429 *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() - | |
| 430 source_clip_box.left; | |
| 431 *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() - | |
| 432 source_clip_box.bottom; | |
| 433 } | |
| 434 | |
| 435 // Calculate the clip box offset for a page that does not need to be scaled. | |
| 436 // All parameters are in points. | |
| 437 // | |
| 438 // |content_rect| specifies the printable area of the destination page, with | |
| 439 // origin at left-bottom. | |
| 440 // |rotation| specifies the source page rotation values which are N / 90 | |
| 441 // degrees. | |
| 442 // |page_width| specifies the screen destination page width. | |
| 443 // |page_height| specifies the screen destination page height. | |
| 444 // |source_clip_box| specifies the source clip box positions, relative to origin | |
| 445 // at left-bottom. | |
| 446 // |offset_x| and |offset_y| will contain the final translation offsets for the | |
| 447 // source clip box, relative to origin at left-bottom. | |
| 448 void CalculateNonScaledClipBoxOffset(const pp::Rect& content_rect, int rotation, | |
| 449 int page_width, int page_height, | |
| 450 const ClipBox& source_clip_box, | |
| 451 double* offset_x, double* offset_y) { | |
| 452 // Align the intended clip region to left-top corner of real clip region. | |
| 453 switch (rotation) { | |
| 454 case 0: | |
| 455 *offset_x = -1 * source_clip_box.left; | |
| 456 *offset_y = page_height - source_clip_box.top; | |
| 457 break; | |
| 458 case 1: | |
| 459 *offset_x = 0; | |
| 460 *offset_y = -1 * source_clip_box.bottom; | |
| 461 break; | |
| 462 case 2: | |
| 463 *offset_x = page_width - source_clip_box.right; | |
| 464 *offset_y = 0; | |
| 465 break; | |
| 466 case 3: | |
| 467 *offset_x = page_height - source_clip_box.right; | |
| 468 *offset_y = page_width - source_clip_box.top; | |
| 469 break; | |
| 470 default: | |
| 471 NOTREACHED(); | |
| 472 break; | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 // This formats a string with special 0xfffe end-of-line hyphens the same way | 328 // This formats a string with special 0xfffe end-of-line hyphens the same way |
| 477 // as Adobe Reader. When a hyphen is encountered, the next non-CR/LF whitespace | 329 // as Adobe Reader. When a hyphen is encountered, the next non-CR/LF whitespace |
| 478 // becomes CR+LF and the hyphen is erased. If there is no whitespace between | 330 // becomes CR+LF and the hyphen is erased. If there is no whitespace between |
| 479 // two hyphens, the latter hyphen is erased and ignored. | 331 // two hyphens, the latter hyphen is erased and ignored. |
| 480 void FormatStringWithHyphens(base::string16* text) { | 332 void FormatStringWithHyphens(base::string16* text) { |
| 481 // First pass marks all the hyphen positions. | 333 // First pass marks all the hyphen positions. |
| 482 struct HyphenPosition { | 334 struct HyphenPosition { |
| 483 HyphenPosition() : position(0), next_whitespace_position(0) {} | 335 HyphenPosition() : position(0), next_whitespace_position(0) {} |
| 484 size_t position; | 336 size_t position; |
| 485 size_t next_whitespace_position; // 0 for none | 337 size_t next_whitespace_position; // 0 for none |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 config.m_pUserFontPaths = nullptr; | 457 config.m_pUserFontPaths = nullptr; |
| 606 config.m_pIsolate = v8::Isolate::GetCurrent(); | 458 config.m_pIsolate = v8::Isolate::GetCurrent(); |
| 607 config.m_v8EmbedderSlot = gin::kEmbedderPDFium; | 459 config.m_v8EmbedderSlot = gin::kEmbedderPDFium; |
| 608 FPDF_InitLibraryWithConfig(&config); | 460 FPDF_InitLibraryWithConfig(&config); |
| 609 | 461 |
| 610 #if defined(OS_LINUX) | 462 #if defined(OS_LINUX) |
| 611 // Font loading doesn't work in the renderer sandbox in Linux. | 463 // Font loading doesn't work in the renderer sandbox in Linux. |
| 612 FPDF_SetSystemFontInfo(&g_font_info); | 464 FPDF_SetSystemFontInfo(&g_font_info); |
| 613 #endif | 465 #endif |
| 614 | 466 |
| 615 FSDK_SetUnSpObjProcessHandler(&g_unsuppored_info); | 467 FSDK_SetUnSpObjProcessHandler(&g_unsupported_info); |
| 616 | 468 |
| 617 return true; | 469 return true; |
| 618 } | 470 } |
| 619 | 471 |
| 620 void ShutdownSDK() { | 472 void ShutdownSDK() { |
| 621 FPDF_DestroyLibrary(); | 473 FPDF_DestroyLibrary(); |
| 622 } | 474 } |
| 623 | 475 |
| 624 PDFEngine* PDFEngine::Create(PDFEngine::Client* client) { | 476 PDFEngine* PDFEngine::Create(PDFEngine::Client* client) { |
| 625 return new PDFiumEngine(client); | 477 return new PDFiumEngine(client); |
| (...skipping 2779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3405 src_page_width > src_page_height, | 3257 src_page_width > src_page_height, |
| 3406 &page_size, | 3258 &page_size, |
| 3407 &content_rect); | 3259 &content_rect); |
| 3408 | 3260 |
| 3409 // Compute the screen page width and height in points. | 3261 // Compute the screen page width and height in points. |
| 3410 const int actual_page_width = | 3262 const int actual_page_width = |
| 3411 rotated ? page_size.height() : page_size.width(); | 3263 rotated ? page_size.height() : page_size.width(); |
| 3412 const int actual_page_height = | 3264 const int actual_page_height = |
| 3413 rotated ? page_size.width() : page_size.height(); | 3265 rotated ? page_size.width() : page_size.height(); |
| 3414 | 3266 |
| 3415 const double scale_factor = CalculateScaleFactor(fit_to_page, content_rect, | 3267 const gfx::Rect gfx_content_rect(content_rect.x(), |
| 3416 src_page_width, | 3268 content_rect.y(), |
| 3417 src_page_height, rotated); | 3269 content_rect.width(), |
| 3270 content_rect.height()); |
| 3271 const double scale_factor = fit_to_page ? |
| 3272 printing::CalculateScaleFactor( |
| 3273 gfx_content_rect, src_page_width, src_page_height, rotated) : 1.0; |
| 3418 | 3274 |
| 3419 // Calculate positions for the clip box. | 3275 // Calculate positions for the clip box. |
| 3420 ClipBox source_clip_box; | 3276 printing::ClipBox media_box; |
| 3421 CalculateClipBoxBoundary(page, scale_factor, rotated, &source_clip_box); | 3277 if (!FPDFPage_GetMediaBox(page, &media_box.left, &media_box.bottom, |
| 3278 &media_box.right, &media_box.top)) { |
| 3279 printing::SetDefaultClipBox(rotated, &media_box); |
| 3280 } |
| 3281 |
| 3282 printing::ClipBox crop_box; |
| 3283 if (!FPDFPage_GetCropBox(page, &crop_box.left, &crop_box.bottom, |
| 3284 &crop_box.right, &crop_box.top)) { |
| 3285 printing::SetDefaultClipBox(rotated, &crop_box); |
| 3286 } |
| 3287 printing::ClipBox source_clip_box = printing::CalculateClipBoxBoundary( |
| 3288 media_box, crop_box, scale_factor, rotated); |
| 3422 | 3289 |
| 3423 // Calculate the translation offset values. | 3290 // Calculate the translation offset values. |
| 3424 double offset_x = 0; | 3291 double offset_x = 0; |
| 3425 double offset_y = 0; | 3292 double offset_y = 0; |
| 3426 if (fit_to_page) { | 3293 if (fit_to_page) { |
| 3427 CalculateScaledClipBoxOffset(content_rect, source_clip_box, &offset_x, | 3294 CalculateScaledClipBoxOffset(gfx_content_rect, source_clip_box, &offset_x, |
| 3428 &offset_y); | 3295 &offset_y); |
| 3429 } else { | 3296 } else { |
| 3430 CalculateNonScaledClipBoxOffset(content_rect, src_page_rotation, | 3297 CalculateNonScaledClipBoxOffset(gfx_content_rect, src_page_rotation, |
| 3431 actual_page_width, actual_page_height, | 3298 actual_page_width, actual_page_height, |
| 3432 source_clip_box, &offset_x, &offset_y); | 3299 source_clip_box, &offset_x, &offset_y); |
| 3433 } | 3300 } |
| 3434 | 3301 |
| 3435 // Reset the media box and crop box. When the page has crop box and media box, | 3302 // Reset the media box and crop box. When the page has crop box and media box, |
| 3436 // the plugin will display the crop box contents and not the entire media box. | 3303 // the plugin will display the crop box contents and not the entire media box. |
| 3437 // If the pages have different crop box values, the plugin will display a | 3304 // If the pages have different crop box values, the plugin will display a |
| 3438 // document of multiple page sizes. To give better user experience, we | 3305 // document of multiple page sizes. To give better user experience, we |
| 3439 // decided to have same crop box and media box values. Hence, the user will | 3306 // decided to have same crop box and media box values. Hence, the user will |
| 3440 // see a list of uniform pages. | 3307 // see a list of uniform pages. |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4097 double* height) { | 3964 double* height) { |
| 4098 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); | 3965 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); |
| 4099 if (!doc) | 3966 if (!doc) |
| 4100 return false; | 3967 return false; |
| 4101 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; | 3968 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; |
| 4102 FPDF_CloseDocument(doc); | 3969 FPDF_CloseDocument(doc); |
| 4103 return success; | 3970 return success; |
| 4104 } | 3971 } |
| 4105 | 3972 |
| 4106 } // namespace chrome_pdf | 3973 } // namespace chrome_pdf |
| OLD | NEW |