Chromium Code Reviews| 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/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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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, ®ion, &stride); | 3008 GetRegion(dirty_in_screen.point(), image_data, ®ion, &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 Loading... | |
| 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 |
| OLD | NEW |