Commit 63443b20 authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Convert some PDF transform code to use gfx::SizeF.

Now that PDFium has APIs to return float values, use them in conjunction
with gfx::SizeF to simplify CalculateScaleFactor() and related code.

Change-Id: I8d8e96c05db5eb6225e9f0a332b69706fa5a2d5d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954770
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723589}
parent ac92dd69
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_f.h"
namespace chrome_pdf { namespace chrome_pdf {
...@@ -25,19 +27,18 @@ void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) { ...@@ -25,19 +27,18 @@ void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
} // namespace } // namespace
double CalculateScaleFactor(const gfx::Rect& content_rect, float CalculateScaleFactor(const gfx::Rect& content_rect,
double src_width, const gfx::SizeF& src_size,
double src_height,
bool rotated) { bool rotated) {
if (src_width == 0 || src_height == 0) if (src_size.IsEmpty())
return 1.0; return 1.0f;
double actual_source_page_width = rotated ? src_height : src_width; float actual_source_page_width =
double actual_source_page_height = rotated ? src_width : src_height; rotated ? src_size.height() : src_size.width();
double ratio_x = float actual_source_page_height =
static_cast<double>(content_rect.width()) / actual_source_page_width; rotated ? src_size.width() : src_size.height();
double ratio_y = float ratio_x = content_rect.width() / actual_source_page_width;
static_cast<double>(content_rect.height()) / actual_source_page_height; float ratio_y = content_rect.height() / actual_source_page_height;
return std::min(ratio_x, ratio_y); return std::min(ratio_x, ratio_y);
} }
...@@ -84,54 +85,45 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box, ...@@ -84,54 +85,45 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
return clip_box; return clip_box;
} }
void ScalePdfRectangle(double scale_factor, PdfRectangle* rect) { void ScalePdfRectangle(float scale_factor, PdfRectangle* rect) {
rect->left *= scale_factor; rect->left *= scale_factor;
rect->bottom *= scale_factor; rect->bottom *= scale_factor;
rect->right *= scale_factor; rect->right *= scale_factor;
rect->top *= scale_factor; rect->top *= scale_factor;
} }
void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect, gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box, const PdfRectangle& source_clip_box) {
double* offset_x,
double* offset_y) {
const float clip_box_width = source_clip_box.right - source_clip_box.left; const float clip_box_width = source_clip_box.right - source_clip_box.left;
const float clip_box_height = source_clip_box.top - source_clip_box.bottom; const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
// Center the intended clip region to real clip region. // Center the intended clip region to real clip region.
*offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() - return gfx::PointF((content_rect.width() - clip_box_width) / 2 +
source_clip_box.left; content_rect.x() - source_clip_box.left,
*offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() - (content_rect.height() - clip_box_height) / 2 +
source_clip_box.bottom; content_rect.y() - source_clip_box.bottom);
} }
void CalculateNonScaledClipBoxOffset(int rotation, gfx::PointF CalculateNonScaledClipBoxOffset(
int rotation,
int page_width, int page_width,
int page_height, int page_height,
const PdfRectangle& source_clip_box, const PdfRectangle& source_clip_box) {
double* offset_x,
double* offset_y) {
// Align the intended clip region to left-top corner of real clip region. // Align the intended clip region to left-top corner of real clip region.
switch (rotation) { switch (rotation) {
case 0: case 0:
*offset_x = -1 * source_clip_box.left; return gfx::PointF(-1 * source_clip_box.left,
*offset_y = page_height - source_clip_box.top; page_height - source_clip_box.top);
break;
case 1: case 1:
*offset_x = 0; return gfx::PointF(0, -1 * source_clip_box.bottom);
*offset_y = -1 * source_clip_box.bottom;
break;
case 2: case 2:
*offset_x = page_width - source_clip_box.right; return gfx::PointF(page_width - source_clip_box.right, 0);
*offset_y = 0;
break;
case 3: case 3:
*offset_x = page_height - source_clip_box.right; return gfx::PointF(page_height - source_clip_box.right,
*offset_y = page_width - source_clip_box.top; page_width - source_clip_box.top);
break;
default: default:
NOTREACHED(); NOTREACHED();
break; return gfx::PointF();
} }
} }
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#define PDF_PDF_TRANSFORM_H_ #define PDF_PDF_TRANSFORM_H_
namespace gfx { namespace gfx {
class PointF;
class Rect; class Rect;
class SizeF;
} }
namespace chrome_pdf { namespace chrome_pdf {
...@@ -20,17 +22,14 @@ struct PdfRectangle { ...@@ -20,17 +22,14 @@ struct PdfRectangle {
float top; float top;
}; };
// Calculate the scale factor between |content_rect| and a page of size // Calculate the scale factor between |content_rect| and a page of |src_size|.
// |src_width| x |src_height|.
// //
// |content_rect| specifies the printable area of the destination page, with // |content_rect| specifies the printable area of the destination page, with
// origin at left-bottom. Values are in points. // origin at left-bottom. Values are in points.
// |src_width| specifies the source page width in points. // |src_size| specifies the source page size in points.
// |src_height| specifies the source page height in points.
// |rotated| True if source page is rotated 90 degree or 270 degree. // |rotated| True if source page is rotated 90 degree or 270 degree.
double CalculateScaleFactor(const gfx::Rect& content_rect, float CalculateScaleFactor(const gfx::Rect& content_rect,
double src_width, const gfx::SizeF& src_size,
double src_height,
bool rotated); bool rotated);
// Make the default size to be letter size (8.5" X 11"). We are just following // Make the default size to be letter size (8.5" X 11"). We are just following
...@@ -58,7 +57,7 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box, ...@@ -58,7 +57,7 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
const PdfRectangle& crop_box); const PdfRectangle& crop_box);
// Scale |rect| by |scale_factor|. // Scale |rect| by |scale_factor|.
void ScalePdfRectangle(double scale_factor, PdfRectangle* rect); void ScalePdfRectangle(float scale_factor, PdfRectangle* rect);
// Calculate the clip box translation offset for a page that does need to be // Calculate the clip box translation offset for a page that does need to be
// scaled. All parameters are in points. // scaled. All parameters are in points.
...@@ -67,12 +66,10 @@ void ScalePdfRectangle(double scale_factor, PdfRectangle* rect); ...@@ -67,12 +66,10 @@ void ScalePdfRectangle(double scale_factor, PdfRectangle* rect);
// origin at left-bottom. // origin at left-bottom.
// |source_clip_box| specifies the source clip box positions, relative to // |source_clip_box| specifies the source clip box positions, relative to
// origin at left-bottom. // origin at left-bottom.
// |offset_x| and |offset_y| will contain the final translation offsets for the // Returns the final translation offsets for the source clip box, relative to
// source clip box, relative to origin at left-bottom. // origin at left-bottom.
void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect, gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box, const PdfRectangle& source_clip_box_);
double* offset_x,
double* offset_y);
// Calculate the clip box offset for a page that does not need to be scaled. // Calculate the clip box offset for a page that does not need to be scaled.
// All parameters are in points. // All parameters are in points.
...@@ -83,14 +80,13 @@ void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect, ...@@ -83,14 +80,13 @@ void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
// |page_height| specifies the screen destination page height. // |page_height| specifies the screen destination page height.
// |source_clip_box| specifies the source clip box positions, relative to origin // |source_clip_box| specifies the source clip box positions, relative to origin
// at left-bottom. // at left-bottom.
// |offset_x| and |offset_y| will contain the final translation offsets for the // Returns the final translation offsets for the source clip box, relative to
// source clip box, relative to origin at left-bottom. // origin at left-bottom.
void CalculateNonScaledClipBoxOffset(int rotation, gfx::PointF CalculateNonScaledClipBoxOffset(
int rotation,
int page_width, int page_width,
int page_height, int page_height,
const PdfRectangle& source_clip_box, const PdfRectangle& source_clip_box);
double* offset_x,
double* offset_y);
} // namespace chrome_pdf } // namespace chrome_pdf
......
This diff is collapsed.
...@@ -22,8 +22,10 @@ ...@@ -22,8 +22,10 @@
#include "third_party/pdfium/public/fpdf_ppo.h" #include "third_party/pdfium/public/fpdf_ppo.h"
#include "third_party/pdfium/public/fpdf_transformpage.h" #include "third_party/pdfium/public/fpdf_transformpage.h"
#include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
using printing::ConvertUnit; using printing::ConvertUnit;
using printing::ConvertUnitDouble; using printing::ConvertUnitDouble;
...@@ -69,17 +71,17 @@ void SetPageSizeAndContentRect(bool rotated, ...@@ -69,17 +71,17 @@ void SetPageSizeAndContentRect(bool rotated,
// Transform |page| contents to fit in the selected printer paper size. // Transform |page| contents to fit in the selected printer paper size.
void TransformPDFPageForPrinting(FPDF_PAGE page, void TransformPDFPageForPrinting(FPDF_PAGE page,
double scale_factor, float scale_factor,
const PP_PrintSettings_Dev& print_settings) { const PP_PrintSettings_Dev& print_settings) {
// Get the source page width and height in points. // Get the source page width and height in points.
const double src_page_width = FPDF_GetPageWidth(page); gfx::SizeF src_page_size(FPDF_GetPageWidthF(page), FPDF_GetPageHeightF(page));
const double src_page_height = FPDF_GetPageHeight(page);
const int src_page_rotation = FPDFPage_GetRotation(page); const int src_page_rotation = FPDFPage_GetRotation(page);
pp::Size page_size(print_settings.paper_size); pp::Size page_size(print_settings.paper_size);
pp::Rect content_rect(print_settings.printable_area); pp::Rect content_rect(print_settings.printable_area);
const bool rotated = (src_page_rotation % 2 == 1); const bool rotated = (src_page_rotation % 2 == 1);
SetPageSizeAndContentRect(rotated, src_page_width > src_page_height, SetPageSizeAndContentRect(rotated,
src_page_size.width() > src_page_size.height(),
&page_size, &content_rect); &page_size, &content_rect);
// Compute the screen page width and height in points. // Compute the screen page width and height in points.
...@@ -106,8 +108,8 @@ void TransformPDFPageForPrinting(FPDF_PAGE page, ...@@ -106,8 +108,8 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
} }
if (fitted_scaling) { if (fitted_scaling) {
scale_factor = CalculateScaleFactor(gfx_printed_rect, src_page_width, scale_factor =
src_page_height, rotated); CalculateScaleFactor(gfx_printed_rect, src_page_size, rotated);
} }
// Calculate positions for the clip box. // Calculate positions for the clip box.
...@@ -124,17 +126,12 @@ void TransformPDFPageForPrinting(FPDF_PAGE page, ...@@ -124,17 +126,12 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
ScalePdfRectangle(scale_factor, &source_clip_box); ScalePdfRectangle(scale_factor, &source_clip_box);
// Calculate the translation offset values. // Calculate the translation offset values.
double offset_x = 0; gfx::PointF offset =
double offset_y = 0; fitted_scaling
? CalculateScaledClipBoxOffset(gfx_printed_rect, source_clip_box)
if (fitted_scaling) { : CalculateNonScaledClipBoxOffset(
CalculateScaledClipBoxOffset(gfx_printed_rect, source_clip_box, &offset_x, src_page_rotation, actual_page_width, actual_page_height,
&offset_y); source_clip_box);
} else {
CalculateNonScaledClipBoxOffset(src_page_rotation, actual_page_width,
actual_page_height, source_clip_box,
&offset_x, &offset_y);
}
// Reset the media box and crop box. When the page has crop box and media box, // Reset the media box and crop box. When the page has crop box and media box,
// the plugin will display the crop box contents and not the entire media box. // the plugin will display the crop box contents and not the entire media box.
...@@ -148,28 +145,23 @@ void TransformPDFPageForPrinting(FPDF_PAGE page, ...@@ -148,28 +145,23 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
// Transformation is not required, return. Do this check only after updating // Transformation is not required, return. Do this check only after updating
// the media box and crop box. For more detailed information, please refer to // the media box and crop box. For more detailed information, please refer to
// the comment block right before FPDF_SetMediaBox and FPDF_GetMediaBox calls. // the comment block right before FPDF_SetMediaBox and FPDF_GetMediaBox calls.
if (scale_factor == 1.0 && offset_x == 0 && offset_y == 0) if (scale_factor == 1.0f && offset.IsOrigin())
return; return;
// All the positions have been calculated, now manipulate the PDF. // All the positions have been calculated, now manipulate the PDF.
FS_MATRIX matrix = {static_cast<float>(scale_factor), const FS_MATRIX matrix = {scale_factor, 0.0f, 0.0f,
0, scale_factor, offset.x(), offset.y()};
0, const FS_RECTF cliprect = {
static_cast<float>(scale_factor), source_clip_box.left + offset.x(), source_clip_box.top + offset.y(),
static_cast<float>(offset_x), source_clip_box.right + offset.x(), source_clip_box.bottom + offset.y()};
static_cast<float>(offset_y)};
FS_RECTF cliprect = {static_cast<float>(source_clip_box.left + offset_x),
static_cast<float>(source_clip_box.top + offset_y),
static_cast<float>(source_clip_box.right + offset_x),
static_cast<float>(source_clip_box.bottom + offset_y)};
FPDFPage_TransFormWithClip(page, &matrix, &cliprect); FPDFPage_TransFormWithClip(page, &matrix, &cliprect);
FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor, offset_x, FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor, offset.x(),
offset_y); offset.y());
} }
void FitContentsToPrintableAreaIfRequired( void FitContentsToPrintableAreaIfRequired(
FPDF_DOCUMENT doc, FPDF_DOCUMENT doc,
double scale_factor, float scale_factor,
const PP_PrintSettings_Dev& print_settings) { const PP_PrintSettings_Dev& print_settings) {
// Check to see if we need to fit pdf contents to printer paper size. // Check to see if we need to fit pdf contents to printer paper size.
if (print_settings.print_scaling_option == PP_PRINTSCALINGOPTION_SOURCE_SIZE) if (print_settings.print_scaling_option == PP_PRINTSCALINGOPTION_SOURCE_SIZE)
...@@ -334,7 +326,7 @@ void PDFiumPrint::FitContentsToPrintableArea(FPDF_DOCUMENT doc, ...@@ -334,7 +326,7 @@ void PDFiumPrint::FitContentsToPrintableArea(FPDF_DOCUMENT doc,
printable_area.height()); printable_area.height());
print_settings.print_scaling_option = print_settings.print_scaling_option =
PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA; PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
FitContentsToPrintableAreaIfRequired(doc, 1.0, print_settings); FitContentsToPrintableAreaIfRequired(doc, 1.0f, print_settings);
} }
std::vector<uint8_t> PDFiumPrint::PrintPagesAsPdf( std::vector<uint8_t> PDFiumPrint::PrintPagesAsPdf(
...@@ -369,7 +361,7 @@ ScopedFPDFDocument PDFiumPrint::CreatePrintPdf( ...@@ -369,7 +361,7 @@ ScopedFPDFDocument PDFiumPrint::CreatePrintPdf(
return nullptr; return nullptr;
} }
double scale_factor = pdf_print_settings.scale_factor / 100.0; float scale_factor = pdf_print_settings.scale_factor / 100.0f;
FitContentsToPrintableAreaIfRequired(output_doc.get(), scale_factor, FitContentsToPrintableAreaIfRequired(output_doc.get(), scale_factor,
print_settings); print_settings);
if (!FlattenPrintData(output_doc.get())) if (!FlattenPrintData(output_doc.get()))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment