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

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

Issue 863043003: PDF: Add a bunch of DCHECKs to make sure we do not go out of bounds. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 1045
1046 void PDFiumEngine::PrePaint() { 1046 void PDFiumEngine::PrePaint() {
1047 for (size_t i = 0; i < progressive_paints_.size(); ++i) 1047 for (size_t i = 0; i < progressive_paints_.size(); ++i)
1048 progressive_paints_[i].painted_ = false; 1048 progressive_paints_[i].painted_ = false;
1049 } 1049 }
1050 1050
1051 void PDFiumEngine::Paint(const pp::Rect& rect, 1051 void PDFiumEngine::Paint(const pp::Rect& rect,
1052 pp::ImageData* image_data, 1052 pp::ImageData* image_data,
1053 std::vector<pp::Rect>* ready, 1053 std::vector<pp::Rect>* ready,
1054 std::vector<pp::Rect>* pending) { 1054 std::vector<pp::Rect>* pending) {
1055 DCHECK(image_data);
1056 DCHECK(ready);
1057 DCHECK(pending);
raymes 2015/01/22 22:50:03 Are these actually useful? I've heard various opin
Lei Zhang 2015/01/22 23:00:09 In the case of: DCHECK(ptr_var); ptr_var->Method(
1058
1055 pp::Rect leftover = rect; 1059 pp::Rect leftover = rect;
1056 for (size_t i = 0; i < visible_pages_.size(); ++i) { 1060 for (size_t i = 0; i < visible_pages_.size(); ++i) {
1057 int index = visible_pages_[i]; 1061 int index = visible_pages_[i];
1058 pp::Rect page_rect = pages_[index]->rect(); 1062 pp::Rect page_rect = pages_[index]->rect();
1059 // Convert the current page's rectangle to screen rectangle. We do this 1063 // Convert the current page's rectangle to screen rectangle. We do this
1060 // instead of the reverse (converting the dirty rectangle from screen to 1064 // instead of the reverse (converting the dirty rectangle from screen to
1061 // page coordinates) because then we'd have to convert back to screen 1065 // page coordinates) because then we'd have to convert back to screen
1062 // coordinates, and the rounding errors sometime leave pixels dirty or even 1066 // coordinates, and the rounding errors sometime leave pixels dirty or even
1063 // move the text up or down a pixel when zoomed. 1067 // move the text up or down a pixel when zoomed.
1064 pp::Rect page_rect_in_screen = GetPageScreenRect(index); 1068 pp::Rect page_rect_in_screen = GetPageScreenRect(index);
1065 pp::Rect dirty_in_screen = page_rect_in_screen.Intersect(leftover); 1069 pp::Rect dirty_in_screen = page_rect_in_screen.Intersect(leftover);
1066 if (dirty_in_screen.IsEmpty()) 1070 if (dirty_in_screen.IsEmpty())
1067 continue; 1071 continue;
1068 1072
1069 leftover = leftover.Subtract(dirty_in_screen); 1073 leftover = leftover.Subtract(dirty_in_screen);
1070 1074
1071 if (pages_[index]->available()) { 1075 if (pages_[index]->available()) {
1072 int progressive = GetProgressiveIndex(index); 1076 int progressive = GetProgressiveIndex(index);
1073 if (progressive != -1 && 1077 if (progressive != -1) {
1074 progressive_paints_[progressive].rect != dirty_in_screen) { 1078 DCHECK_GE(progressive, 0);
1075 // The PDFium code can only handle one progressive paint at a time, so 1079 DCHECK_LT(static_cast<size_t>(progressive), progressive_paints_.size());
1076 // queue this up. Previously we used to merge the rects when this 1080 if (progressive_paints_[progressive].rect != dirty_in_screen) {
1077 // happened, but it made scrolling up on complex PDFs very slow since 1081 // The PDFium code can only handle one progressive paint at a time, so
1078 // there would be a damaged rect at the top (from scroll) and at the 1082 // queue this up. Previously we used to merge the rects when this
1079 // bottom (from toolbar). 1083 // happened, but it made scrolling up on complex PDFs very slow since
1080 pending->push_back(dirty_in_screen); 1084 // there would be a damaged rect at the top (from scroll) and at the
1081 continue; 1085 // bottom (from toolbar).
1086 pending->push_back(dirty_in_screen);
1087 continue;
1088 }
1082 } 1089 }
1083 1090
1084 if (progressive == -1) { 1091 if (progressive == -1) {
raymes 2015/01/22 22:50:03 can we make this an "else" branch of the previous
Lei Zhang 2015/01/22 23:00:09 I thought about it, but I can also see the argumen
1085 progressive = StartPaint(index, dirty_in_screen); 1092 progressive = StartPaint(index, dirty_in_screen);
1086 progressive_paint_timeout_ = kMaxInitialProgressivePaintTimeMs; 1093 progressive_paint_timeout_ = kMaxInitialProgressivePaintTimeMs;
1087 } else { 1094 } else {
1088 progressive_paint_timeout_ = kMaxProgressivePaintTimeMs; 1095 progressive_paint_timeout_ = kMaxProgressivePaintTimeMs;
raymes 2015/01/22 22:50:03 Can this go into the previous if-statement?
1089 } 1096 }
1090 1097
1091 progressive_paints_[progressive].painted_ = true; 1098 progressive_paints_[progressive].painted_ = true;
1092 if (ContinuePaint(progressive, image_data)) { 1099 if (ContinuePaint(progressive, image_data)) {
1093 FinishPaint(progressive, image_data); 1100 FinishPaint(progressive, image_data);
1094 ready->push_back(dirty_in_screen); 1101 ready->push_back(dirty_in_screen);
1095 } else { 1102 } else {
1096 pending->push_back(dirty_in_screen); 1103 pending->push_back(dirty_in_screen);
1097 } 1104 }
1098 } else { 1105 } else {
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2334 return (permissions_ & kPDFPermissionCopyMask) != 0; 2341 return (permissions_ & kPDFPermissionCopyMask) != 0;
2335 case PERMISSION_COPY_ACCESSIBLE: 2342 case PERMISSION_COPY_ACCESSIBLE:
2336 return (permissions_ & kPDFPermissionCopyAccessibleMask) != 0; 2343 return (permissions_ & kPDFPermissionCopyAccessibleMask) != 0;
2337 case PERMISSION_PRINT_LOW_QUALITY: 2344 case PERMISSION_PRINT_LOW_QUALITY:
2338 return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0; 2345 return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0;
2339 case PERMISSION_PRINT_HIGH_QUALITY: 2346 case PERMISSION_PRINT_HIGH_QUALITY:
2340 return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0 && 2347 return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0 &&
2341 (permissions_ & kPDFPermissionPrintHighQualityMask) != 0; 2348 (permissions_ & kPDFPermissionPrintHighQualityMask) != 0;
2342 default: 2349 default:
2343 return true; 2350 return true;
2344 }; 2351 }
2345 } 2352 }
2346 2353
2347 void PDFiumEngine::SelectAll() { 2354 void PDFiumEngine::SelectAll() {
2348 SelectionChangeInvalidator selection_invalidator(this); 2355 SelectionChangeInvalidator selection_invalidator(this);
2349 2356
2350 selection_.clear(); 2357 selection_.clear();
2351 for (size_t i = 0; i < pages_.size(); ++i) 2358 for (size_t i = 0; i < pages_.size(); ++i)
2352 if (pages_[i]->available()) { 2359 if (pages_[i]->available()) {
2353 selection_.push_back(PDFiumRange(pages_[i], 0, 2360 selection_.push_back(PDFiumRange(pages_[i], 0,
2354 pages_[i]->GetCharCount())); 2361 pages_[i]->GetCharCount()));
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 progressive.rect = dirty; 2838 progressive.rect = dirty;
2832 progressive.page_index = page_index; 2839 progressive.page_index = page_index;
2833 progressive.bitmap = NULL; 2840 progressive.bitmap = NULL;
2834 progressive.painted_ = false; 2841 progressive.painted_ = false;
2835 progressive_paints_.push_back(progressive); 2842 progressive_paints_.push_back(progressive);
2836 return progressive_paints_.size() - 1; 2843 return progressive_paints_.size() - 1;
2837 } 2844 }
2838 2845
2839 bool PDFiumEngine::ContinuePaint(int progressive_index, 2846 bool PDFiumEngine::ContinuePaint(int progressive_index,
2840 pp::ImageData* image_data) { 2847 pp::ImageData* image_data) {
2848 DCHECK_GE(progressive_index, 0);
2849 DCHECK_LT(static_cast<size_t>(progressive_index), progressive_paints_.size());
2850 DCHECK(image_data);
2851
2841 #if defined(OS_LINUX) 2852 #if defined(OS_LINUX)
2842 g_last_instance_id = client_->GetPluginInstance()->pp_instance(); 2853 g_last_instance_id = client_->GetPluginInstance()->pp_instance();
2843 #endif 2854 #endif
2844 2855
2845 int rv; 2856 int rv;
2857 FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
2846 int page_index = progressive_paints_[progressive_index].page_index; 2858 int page_index = progressive_paints_[progressive_index].page_index;
2859 DCHECK_GE(page_index, 0);
2860 DCHECK_LT(static_cast<size_t>(page_index), pages_.size());
2861 FPDF_PAGE page = pages_[page_index]->GetPage();
2862
2847 last_progressive_start_time_ = base::Time::Now(); 2863 last_progressive_start_time_ = base::Time::Now();
2848 if (progressive_paints_[progressive_index].bitmap) { 2864 if (bitmap) {
2849 rv = FPDF_RenderPage_Continue( 2865 rv = FPDF_RenderPage_Continue(page, static_cast<IFSDK_PAUSE*>(this));
2850 pages_[page_index]->GetPage(), static_cast<IFSDK_PAUSE*>(this));
2851 } else { 2866 } else {
2852 pp::Rect dirty = progressive_paints_[progressive_index].rect; 2867 pp::Rect dirty = progressive_paints_[progressive_index].rect;
2853 progressive_paints_[progressive_index].bitmap = CreateBitmap(dirty, 2868 bitmap = CreateBitmap(dirty, image_data);
2854 image_data);
2855 int start_x, start_y, size_x, size_y; 2869 int start_x, start_y, size_x, size_y;
2856 GetPDFiumRect( 2870 GetPDFiumRect(page_index, dirty, &start_x, &start_y, &size_x, &size_y);
2857 page_index, dirty, &start_x, &start_y, &size_x, &size_y); 2871 FPDFBitmap_FillRect(bitmap, start_x, start_y, size_x, size_y, 0xFFFFFFFF);
2858 FPDFBitmap_FillRect(progressive_paints_[progressive_index].bitmap, start_x,
2859 start_y, size_x, size_y, 0xFFFFFFFF);
2860 rv = FPDF_RenderPageBitmap_Start( 2872 rv = FPDF_RenderPageBitmap_Start(
2861 progressive_paints_[progressive_index].bitmap, 2873 bitmap, page, start_x, start_y, size_x, size_y,
2862 pages_[page_index]->GetPage(), start_x, start_y, size_x, size_y,
2863 current_rotation_, 2874 current_rotation_,
2864 GetRenderingFlags(), static_cast<IFSDK_PAUSE*>(this)); 2875 GetRenderingFlags(), static_cast<IFSDK_PAUSE*>(this));
2876 progressive_paints_[progressive_index].bitmap = bitmap;
2865 } 2877 }
2866 return rv != FPDF_RENDER_TOBECOUNTINUED; 2878 return rv != FPDF_RENDER_TOBECOUNTINUED;
2867 } 2879 }
2868 2880
2869 void PDFiumEngine::FinishPaint(int progressive_index, 2881 void PDFiumEngine::FinishPaint(int progressive_index,
2870 pp::ImageData* image_data) { 2882 pp::ImageData* image_data) {
2883 DCHECK_GE(progressive_index, 0);
2884 DCHECK_LT(static_cast<size_t>(progressive_index), progressive_paints_.size());
2885 DCHECK(image_data);
2886
2871 int page_index = progressive_paints_[progressive_index].page_index; 2887 int page_index = progressive_paints_[progressive_index].page_index;
2872 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect; 2888 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2873 FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap; 2889 FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
2874 int start_x, start_y, size_x, size_y; 2890 int start_x, start_y, size_x, size_y;
2875 GetPDFiumRect( 2891 GetPDFiumRect(
2876 page_index, dirty_in_screen, &start_x, &start_y, &size_x, &size_y); 2892 page_index, dirty_in_screen, &start_x, &start_y, &size_x, &size_y);
2877 2893
2878 // Draw the forms. 2894 // Draw the forms.
2879 FPDF_FFLDraw( 2895 FPDF_FFLDraw(
2880 form_, bitmap, pages_[page_index]->GetPage(), start_x, start_y, size_x, 2896 form_, bitmap, pages_[page_index]->GetPage(), start_x, start_y, size_x,
(...skipping 15 matching lines...) Expand all
2896 2912
2897 void PDFiumEngine::CancelPaints() { 2913 void PDFiumEngine::CancelPaints() {
2898 for (size_t i = 0; i < progressive_paints_.size(); ++i) { 2914 for (size_t i = 0; i < progressive_paints_.size(); ++i) {
2899 FPDF_RenderPage_Close(pages_[progressive_paints_[i].page_index]->GetPage()); 2915 FPDF_RenderPage_Close(pages_[progressive_paints_[i].page_index]->GetPage());
2900 FPDFBitmap_Destroy(progressive_paints_[i].bitmap); 2916 FPDFBitmap_Destroy(progressive_paints_[i].bitmap);
2901 } 2917 }
2902 progressive_paints_.clear(); 2918 progressive_paints_.clear();
2903 } 2919 }
2904 2920
2905 void PDFiumEngine::FillPageSides(int progressive_index) { 2921 void PDFiumEngine::FillPageSides(int progressive_index) {
2922 DCHECK_GE(progressive_index, 0);
2923 DCHECK_LT(static_cast<size_t>(progressive_index), progressive_paints_.size());
2924
2906 int page_index = progressive_paints_[progressive_index].page_index; 2925 int page_index = progressive_paints_[progressive_index].page_index;
2907 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect; 2926 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2908 FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap; 2927 FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
2909 2928
2910 pp::Rect page_rect = pages_[page_index]->rect(); 2929 pp::Rect page_rect = pages_[page_index]->rect();
2911 if (page_rect.x() > 0) { 2930 if (page_rect.x() > 0) {
2912 pp::Rect left(0, 2931 pp::Rect left(0,
2913 page_rect.y() - kPageShadowTop, 2932 page_rect.y() - kPageShadowTop,
2914 page_rect.x() - kPageShadowLeft, 2933 page_rect.x() - kPageShadowLeft,
2915 page_rect.height() + kPageShadowTop + 2934 page_rect.height() + kPageShadowTop +
(...skipping 26 matching lines...) Expand all
2942 kPageSeparatorThickness); 2961 kPageSeparatorThickness);
2943 bottom = GetScreenRect(bottom).Intersect(dirty_in_screen); 2962 bottom = GetScreenRect(bottom).Intersect(dirty_in_screen);
2944 2963
2945 FPDFBitmap_FillRect(bitmap, bottom.x() - dirty_in_screen.x(), 2964 FPDFBitmap_FillRect(bitmap, bottom.x() - dirty_in_screen.x(),
2946 bottom.y() - dirty_in_screen.y(), bottom.width(), 2965 bottom.y() - dirty_in_screen.y(), bottom.width(),
2947 bottom.height(), kBackgroundColor); 2966 bottom.height(), kBackgroundColor);
2948 } 2967 }
2949 2968
2950 void PDFiumEngine::PaintPageShadow(int progressive_index, 2969 void PDFiumEngine::PaintPageShadow(int progressive_index,
2951 pp::ImageData* image_data) { 2970 pp::ImageData* image_data) {
2971 DCHECK_GE(progressive_index, 0);
2972 DCHECK_LT(static_cast<size_t>(progressive_index), progressive_paints_.size());
2973 DCHECK(image_data);
2974
2952 int page_index = progressive_paints_[progressive_index].page_index; 2975 int page_index = progressive_paints_[progressive_index].page_index;
2953 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect; 2976 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2954 pp::Rect page_rect = pages_[page_index]->rect(); 2977 pp::Rect page_rect = pages_[page_index]->rect();
2955 pp::Rect shadow_rect(page_rect); 2978 pp::Rect shadow_rect(page_rect);
2956 shadow_rect.Inset(-kPageShadowLeft, -kPageShadowTop, 2979 shadow_rect.Inset(-kPageShadowLeft, -kPageShadowTop,
2957 -kPageShadowRight, -kPageShadowBottom); 2980 -kPageShadowRight, -kPageShadowBottom);
2958 2981
2959 // Due to the rounding errors of the GetScreenRect it is possible to get 2982 // Due to the rounding errors of the GetScreenRect it is possible to get
2960 // different size shadows on the left and right sides even they are defined 2983 // different size shadows on the left and right sides even they are defined
2961 // the same. To fix this issue let's calculate shadow rect and then shrink 2984 // the same. To fix this issue let's calculate shadow rect and then shrink
2962 // it by the size of the shadows. 2985 // it by the size of the shadows.
2963 shadow_rect = GetScreenRect(shadow_rect); 2986 shadow_rect = GetScreenRect(shadow_rect);
2964 page_rect = shadow_rect; 2987 page_rect = shadow_rect;
2965 2988
2966 page_rect.Inset(static_cast<int>(ceil(kPageShadowLeft * current_zoom_)), 2989 page_rect.Inset(static_cast<int>(ceil(kPageShadowLeft * current_zoom_)),
2967 static_cast<int>(ceil(kPageShadowTop * current_zoom_)), 2990 static_cast<int>(ceil(kPageShadowTop * current_zoom_)),
2968 static_cast<int>(ceil(kPageShadowRight * current_zoom_)), 2991 static_cast<int>(ceil(kPageShadowRight * current_zoom_)),
2969 static_cast<int>(ceil(kPageShadowBottom * current_zoom_))); 2992 static_cast<int>(ceil(kPageShadowBottom * current_zoom_)));
2970 2993
2971 DrawPageShadow(page_rect, shadow_rect, dirty_in_screen, image_data); 2994 DrawPageShadow(page_rect, shadow_rect, dirty_in_screen, image_data);
2972 } 2995 }
2973 2996
2974 void PDFiumEngine::DrawSelections(int progressive_index, 2997 void PDFiumEngine::DrawSelections(int progressive_index,
2975 pp::ImageData* image_data) { 2998 pp::ImageData* image_data) {
2999 DCHECK_GE(progressive_index, 0);
3000 DCHECK_LT(static_cast<size_t>(progressive_index), progressive_paints_.size());
3001 DCHECK(image_data);
3002
2976 int page_index = progressive_paints_[progressive_index].page_index; 3003 int page_index = progressive_paints_[progressive_index].page_index;
2977 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect; 3004 pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
2978 3005
2979 void* region = NULL; 3006 void* region = NULL;
2980 int stride; 3007 int stride;
2981 GetRegion(dirty_in_screen.point(), image_data, &region, &stride); 3008 GetRegion(dirty_in_screen.point(), image_data, &region, &stride);
2982 3009
2983 std::vector<pp::Rect> highlighted_rects; 3010 std::vector<pp::Rect> highlighted_rects;
2984 pp::Rect visible_rect = GetVisibleRect(); 3011 pp::Rect visible_rect = GetVisibleRect();
2985 for (size_t k = 0; k < selection_.size(); ++k) { 3012 for (size_t k = 0; k < selection_.size(); ++k) {
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
3991 double* height) { 4018 double* height) {
3992 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL); 4019 FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL);
3993 if (!doc) 4020 if (!doc)
3994 return false; 4021 return false;
3995 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0; 4022 bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0;
3996 FPDF_CloseDocument(doc); 4023 FPDF_CloseDocument(doc);
3997 return success; 4024 return success;
3998 } 4025 }
3999 4026
4000 } // namespace chrome_pdf 4027 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698