Index: pdf/pdfium/pdfium_engine.cc |
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc |
index 35c28964955714d9612abb991075277b904480e0..e907e3b85a7168a45ea96701ca70e18e7f597d9c 100644 |
--- a/pdf/pdfium/pdfium_engine.cc |
+++ b/pdf/pdfium/pdfium_engine.cc |
@@ -57,6 +57,7 @@ |
#include "third_party/pdfium/public/fpdf_transformpage.h" |
#include "third_party/pdfium/public/fpdfview.h" |
#include "ui/events/keycodes/keyboard_codes.h" |
+#include "ui/gfx/codec/jpeg_codec.h" |
#include "ui/gfx/geometry/rect.h" |
#include "v8/include/v8.h" |
@@ -1355,7 +1356,9 @@ bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) { |
uint32_t PDFiumEngine::QuerySupportedPrintOutputFormats() { |
if (!HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY)) |
Tom Sepez
2016/12/14 20:32:54
nit:
Can a document have high_quality but not l
rbpotter
2016/12/15 00:50:59
Based on the logic in HasPermission, if a document
Tom Sepez
2016/12/15 21:09:23
Lots better, thanks.
|
return 0; |
- return PP_PRINTOUTPUTFORMAT_PDF; |
+ if (!HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) |
+ return PP_PRINTOUTPUTFORMAT_RASTER; |
+ return PP_PRINTOUTPUTFORMAT_PDF | PP_PRINTOUTPUTFORMAT_RASTER; |
} |
void PDFiumEngine::PrintBegin() { |
@@ -1366,13 +1369,32 @@ pp::Resource PDFiumEngine::PrintPages( |
const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count, |
const PP_PrintSettings_Dev& print_settings) { |
ScopedSubstFont scoped_subst_font(this); |
- if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) |
+ if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY) && |
+ (print_settings.format & PP_PRINTOUTPUTFORMAT_PDF)) { |
return PrintPagesAsPDF(page_ranges, page_range_count, print_settings); |
- else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY)) |
+ } else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY)) { |
return PrintPagesAsRasterPDF(page_ranges, page_range_count, print_settings); |
+ } |
+ |
return pp::Resource(); |
} |
+struct simple_buf { |
+ uint32_t size; |
+ uint8_t *data; |
Tom Sepez
2016/12/14 20:32:54
nit: uint8_t* data; per style guide (several place
rbpotter
2016/12/15 00:50:58
Done.
|
+}; |
+ |
+int GetBlockForJpeg(void *param, |
Tom Sepez
2016/12/14 20:32:54
the return type should probably be unsigned long t
rbpotter
2016/12/15 00:50:59
Unfortunately the signature is determined by the F
|
+ unsigned long pos, |
+ unsigned char* pBuf, |
Tom Sepez
2016/12/14 20:32:55
nit: uint8_t consistently throughout, hungarian no
rbpotter
2016/12/15 00:50:59
The signature for this function is defined by the
|
+ unsigned long size) { |
+ simple_buf * buf_p = static_cast<simple_buf *>(param); |
+ if (pos + size < pos || pos + size > buf_p->size) |
dsinclair
2016/12/14 19:54:38
The pos + size < pos seems like it would always be
Tom Sepez
2016/12/14 20:32:54
This is checking for overflow, and is allowed in t
|
+ return 0; |
+ memcpy(pBuf, buf_p->data, size); |
dsinclair
2016/12/14 19:54:38
Should this be copying from buf_p->data + pos? Won
dsinclair
2016/12/14 19:54:38
Is it safe to assume pBuf is always big enough her
rbpotter
2016/12/15 00:50:58
Since the buffer is provided by the caller I don't
rbpotter
2016/12/15 00:50:58
Done.
Tom Sepez
2016/12/15 21:09:23
I think this is still an issue.
rbpotter
2016/12/16 00:06:31
This is now copying size bytes from buf_p->data.si
|
+ return size; |
+} |
dsinclair
2016/12/14 19:54:38
Move up into the anonymous namespace.
rbpotter
2016/12/15 00:50:59
Done.
|
+ |
FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf( |
double source_page_width, |
double source_page_height, |
@@ -1412,6 +1434,8 @@ FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf( |
print_settings.orientation, |
FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH); |
+ unsigned char * bitmap_data = |
+ static_cast<unsigned char *>(FPDFBitmap_GetBuffer(bitmap)); |
double ratio_x = ConvertUnitDouble(bitmap_size.width(), |
print_settings.dpi, |
kPointsPerInch); |
@@ -1422,7 +1446,36 @@ FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf( |
// Add the bitmap to an image object and add the image object to the output |
// page. |
FPDF_PAGEOBJECT temp_img = FPDFPageObj_NewImgeObj(temp_doc); |
- FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap); |
+ |
+ std::vector <unsigned char> compressed_bitmap_data; |
Tom Sepez
2016/12/14 20:32:54
nit: std::vector<uint8_t>
Did you "git cl format"
rbpotter
2016/12/15 00:50:58
Done.
|
+ int quality = 40; |
+ bool encode_success = gfx::JPEGCodec::Encode(bitmap_data, |
dsinclair
2016/12/14 19:54:38
Do we always want to do the JPEG encode, or only w
Tom Sepez
2016/12/14 20:32:54
nit: local not needed
rbpotter
2016/12/15 00:50:58
Not sure. The JPEG encode saves space for big/imag
|
+ gfx::JPEGCodec::FORMAT_BGRA, |
+ FPDFBitmap_GetWidth(bitmap), |
+ FPDFBitmap_GetHeight(bitmap), |
+ FPDFBitmap_GetStride(bitmap), |
+ quality, |
+ &compressed_bitmap_data); |
+ |
+ if (encode_success) { |
+ simple_buf buffer; |
+ buffer.size = compressed_bitmap_data.size(); |
Tom Sepez
2016/12/14 20:32:54
beware, this truncates a size_t to an uint32_t. Y
rbpotter
2016/12/15 00:50:58
Done.
|
+ buffer.data = new uint8_t[buffer.size]; |
Tom Sepez
2016/12/14 20:36:28
actually, we can set buffer.data to compressed_bit
rbpotter
2016/12/15 00:50:58
Done.
|
+ memcpy(buffer.data, &(compressed_bitmap_data[0]), buffer.size); |
+ |
+ FPDF_FILEACCESS file_access; |
+ memset(&file_access, '\0', sizeof(file_access)); |
+ file_access.m_FileLen = |
+ static_cast<unsigned long>(compressed_bitmap_data.size()); |
+ file_access.m_GetBlock = &GetBlockForJpeg; |
+ file_access.m_Param = &buffer; |
+ |
+ FPDFImageObj_LoadJpegFileInline(&temp_page, 1, temp_img, &file_access); |
+ delete buffer.data; |
Tom Sepez
2016/12/14 20:32:54
delete[] buffer.data?
rbpotter
2016/12/15 00:50:59
N/A
|
+ } else { |
+ FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap); |
+ } |
+ |
FPDFImageObj_SetMatrix(temp_img, ratio_x, 0, 0, ratio_y, 0, 0); |
FPDFPage_InsertObject(temp_page, temp_img); |
FPDFPage_GenerateContent(temp_page); |