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 @@
#include <utility>
#include "base/logging.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_f.h"
namespace chrome_pdf {
......@@ -25,19 +27,18 @@ void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
} // namespace
double CalculateScaleFactor(const gfx::Rect& content_rect,
double src_width,
double src_height,
bool rotated) {
if (src_width == 0 || src_height == 0)
return 1.0;
double actual_source_page_width = rotated ? src_height : src_width;
double actual_source_page_height = rotated ? src_width : src_height;
double ratio_x =
static_cast<double>(content_rect.width()) / actual_source_page_width;
double ratio_y =
static_cast<double>(content_rect.height()) / actual_source_page_height;
float CalculateScaleFactor(const gfx::Rect& content_rect,
const gfx::SizeF& src_size,
bool rotated) {
if (src_size.IsEmpty())
return 1.0f;
float actual_source_page_width =
rotated ? src_size.height() : src_size.width();
float actual_source_page_height =
rotated ? src_size.width() : src_size.height();
float ratio_x = content_rect.width() / actual_source_page_width;
float ratio_y = content_rect.height() / actual_source_page_height;
return std::min(ratio_x, ratio_y);
}
......@@ -84,54 +85,45 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
return clip_box;
}
void ScalePdfRectangle(double scale_factor, PdfRectangle* rect) {
void ScalePdfRectangle(float scale_factor, PdfRectangle* rect) {
rect->left *= scale_factor;
rect->bottom *= scale_factor;
rect->right *= scale_factor;
rect->top *= scale_factor;
}
void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box,
double* offset_x,
double* offset_y) {
gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box) {
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;
// Center the intended clip region to real clip region.
*offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
source_clip_box.left;
*offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
source_clip_box.bottom;
return gfx::PointF((content_rect.width() - clip_box_width) / 2 +
content_rect.x() - source_clip_box.left,
(content_rect.height() - clip_box_height) / 2 +
content_rect.y() - source_clip_box.bottom);
}
void CalculateNonScaledClipBoxOffset(int rotation,
int page_width,
int page_height,
const PdfRectangle& source_clip_box,
double* offset_x,
double* offset_y) {
gfx::PointF CalculateNonScaledClipBoxOffset(
int rotation,
int page_width,
int page_height,
const PdfRectangle& source_clip_box) {
// Align the intended clip region to left-top corner of real clip region.
switch (rotation) {
case 0:
*offset_x = -1 * source_clip_box.left;
*offset_y = page_height - source_clip_box.top;
break;
return gfx::PointF(-1 * source_clip_box.left,
page_height - source_clip_box.top);
case 1:
*offset_x = 0;
*offset_y = -1 * source_clip_box.bottom;
break;
return gfx::PointF(0, -1 * source_clip_box.bottom);
case 2:
*offset_x = page_width - source_clip_box.right;
*offset_y = 0;
break;
return gfx::PointF(page_width - source_clip_box.right, 0);
case 3:
*offset_x = page_height - source_clip_box.right;
*offset_y = page_width - source_clip_box.top;
break;
return gfx::PointF(page_height - source_clip_box.right,
page_width - source_clip_box.top);
default:
NOTREACHED();
break;
return gfx::PointF();
}
}
......
......@@ -6,7 +6,9 @@
#define PDF_PDF_TRANSFORM_H_
namespace gfx {
class PointF;
class Rect;
class SizeF;
}
namespace chrome_pdf {
......@@ -20,18 +22,15 @@ struct PdfRectangle {
float top;
};
// Calculate the scale factor between |content_rect| and a page of size
// |src_width| x |src_height|.
// Calculate the scale factor between |content_rect| and a page of |src_size|.
//
// |content_rect| specifies the printable area of the destination page, with
// origin at left-bottom. Values are in points.
// |src_width| specifies the source page width in points.
// |src_height| specifies the source page height in points.
// |src_size| specifies the source page size in points.
// |rotated| True if source page is rotated 90 degree or 270 degree.
double CalculateScaleFactor(const gfx::Rect& content_rect,
double src_width,
double src_height,
bool rotated);
float CalculateScaleFactor(const gfx::Rect& content_rect,
const gfx::SizeF& src_size,
bool rotated);
// Make the default size to be letter size (8.5" X 11"). We are just following
// the PDFium way of handling these corner cases. PDFium always consider
......@@ -58,7 +57,7 @@ PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
const PdfRectangle& crop_box);
// 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
// scaled. All parameters are in points.
......@@ -67,12 +66,10 @@ void ScalePdfRectangle(double scale_factor, PdfRectangle* rect);
// origin at left-bottom.
// |source_clip_box| specifies the source clip box positions, relative to
// origin at left-bottom.
// |offset_x| and |offset_y| will contain the final translation offsets for the
// source clip box, relative to origin at left-bottom.
void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box,
double* offset_x,
double* offset_y);
// Returns the final translation offsets for the source clip box, relative to
// origin at left-bottom.
gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
const PdfRectangle& source_clip_box_);
// Calculate the clip box offset for a page that does not need to be scaled.
// All parameters are in points.
......@@ -83,14 +80,13 @@ void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
// |page_height| specifies the screen destination page height.
// |source_clip_box| specifies the source clip box positions, relative to origin
// at left-bottom.
// |offset_x| and |offset_y| will contain the final translation offsets for the
// source clip box, relative to origin at left-bottom.
void CalculateNonScaledClipBoxOffset(int rotation,
int page_width,
int page_height,
const PdfRectangle& source_clip_box,
double* offset_x,
double* offset_y);
// Returns the final translation offsets for the source clip box, relative to
// origin at left-bottom.
gfx::PointF CalculateNonScaledClipBoxOffset(
int rotation,
int page_width,
int page_height,
const PdfRectangle& source_clip_box);
} // namespace chrome_pdf
......
This diff is collapsed.
......@@ -22,8 +22,10 @@
#include "third_party/pdfium/public/fpdf_ppo.h"
#include "third_party/pdfium/public/fpdf_transformpage.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/size.h"
#include "ui/gfx/geometry/size_f.h"
using printing::ConvertUnit;
using printing::ConvertUnitDouble;
......@@ -69,17 +71,17 @@ void SetPageSizeAndContentRect(bool rotated,
// Transform |page| contents to fit in the selected printer paper size.
void TransformPDFPageForPrinting(FPDF_PAGE page,
double scale_factor,
float scale_factor,
const PP_PrintSettings_Dev& print_settings) {
// Get the source page width and height in points.
const double src_page_width = FPDF_GetPageWidth(page);
const double src_page_height = FPDF_GetPageHeight(page);
gfx::SizeF src_page_size(FPDF_GetPageWidthF(page), FPDF_GetPageHeightF(page));
const int src_page_rotation = FPDFPage_GetRotation(page);
pp::Size page_size(print_settings.paper_size);
pp::Rect content_rect(print_settings.printable_area);
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);
// Compute the screen page width and height in points.
......@@ -106,8 +108,8 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
}
if (fitted_scaling) {
scale_factor = CalculateScaleFactor(gfx_printed_rect, src_page_width,
src_page_height, rotated);
scale_factor =
CalculateScaleFactor(gfx_printed_rect, src_page_size, rotated);
}
// Calculate positions for the clip box.
......@@ -124,17 +126,12 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
ScalePdfRectangle(scale_factor, &source_clip_box);
// Calculate the translation offset values.
double offset_x = 0;
double offset_y = 0;
if (fitted_scaling) {
CalculateScaledClipBoxOffset(gfx_printed_rect, source_clip_box, &offset_x,
&offset_y);
} else {
CalculateNonScaledClipBoxOffset(src_page_rotation, actual_page_width,
actual_page_height, source_clip_box,
&offset_x, &offset_y);
}
gfx::PointF offset =
fitted_scaling
? CalculateScaledClipBoxOffset(gfx_printed_rect, source_clip_box)
: CalculateNonScaledClipBoxOffset(
src_page_rotation, actual_page_width, actual_page_height,
source_clip_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.
......@@ -148,28 +145,23 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
// 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 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;
// All the positions have been calculated, now manipulate the PDF.
FS_MATRIX matrix = {static_cast<float>(scale_factor),
0,
0,
static_cast<float>(scale_factor),
static_cast<float>(offset_x),
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)};
const FS_MATRIX matrix = {scale_factor, 0.0f, 0.0f,
scale_factor, offset.x(), offset.y()};
const FS_RECTF cliprect = {
source_clip_box.left + offset.x(), source_clip_box.top + offset.y(),
source_clip_box.right + offset.x(), source_clip_box.bottom + offset.y()};
FPDFPage_TransFormWithClip(page, &matrix, &cliprect);
FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor, offset_x,
offset_y);
FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor, offset.x(),
offset.y());
}
void FitContentsToPrintableAreaIfRequired(
FPDF_DOCUMENT doc,
double scale_factor,
float scale_factor,
const PP_PrintSettings_Dev& print_settings) {
// Check to see if we need to fit pdf contents to printer paper size.
if (print_settings.print_scaling_option == PP_PRINTSCALINGOPTION_SOURCE_SIZE)
......@@ -334,7 +326,7 @@ void PDFiumPrint::FitContentsToPrintableArea(FPDF_DOCUMENT doc,
printable_area.height());
print_settings.print_scaling_option =
PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
FitContentsToPrintableAreaIfRequired(doc, 1.0, print_settings);
FitContentsToPrintableAreaIfRequired(doc, 1.0f, print_settings);
}
std::vector<uint8_t> PDFiumPrint::PrintPagesAsPdf(
......@@ -369,7 +361,7 @@ ScopedFPDFDocument PDFiumPrint::CreatePrintPdf(
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,
print_settings);
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