1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "pdf/pdf_transform.h"
10 #include "base/logging.h"
11 #include "ui/gfx/geometry/rect.h"
13 namespace chrome_pdf {
17 // When a PdfRectangle has top < bottom, or right < left, the values should be
19 void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
20 if (rect->top < rect->bottom)
21 std::swap(rect->top, rect->bottom);
22 if (rect->right < rect->left)
23 std::swap(rect->right, rect->left);
28 double CalculateScaleFactor(const gfx::Rect& content_rect,
32 if (src_width == 0 || src_height == 0)
35 double actual_source_page_width = rotated ? src_height : src_width;
36 double actual_source_page_height = rotated ? src_width : src_height;
38 static_cast<double>(content_rect.width()) / actual_source_page_width;
40 static_cast<double>(content_rect.height()) / actual_source_page_height;
41 return std::min(ratio_x, ratio_y);
44 void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) {
45 constexpr int kDpi = 72;
46 constexpr float kPaperWidth = 8.5 * kDpi;
47 constexpr float kPaperHeight = 11 * kDpi;
50 clip_box->right = rotated ? kPaperHeight : kPaperWidth;
51 clip_box->top = rotated ? kPaperWidth : kPaperHeight;
54 void CalculateMediaBoxAndCropBox(bool rotated,
57 PdfRectangle* media_box,
58 PdfRectangle* crop_box) {
60 SwapPdfRectangleValuesIfNeeded(media_box);
62 SwapPdfRectangleValuesIfNeeded(crop_box);
64 if (!has_media_box && !has_crop_box) {
65 SetDefaultClipBox(rotated, crop_box);
66 SetDefaultClipBox(rotated, media_box);
67 } else if (has_crop_box && !has_media_box) {
68 *media_box = *crop_box;
69 } else if (has_media_box && !has_crop_box) {
70 *crop_box = *media_box;
74 PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
75 const PdfRectangle& crop_box) {
76 PdfRectangle clip_box;
78 // Clip |media_box| to the size of |crop_box|, but ignore |crop_box| if it is
79 // bigger than |media_box|.
80 clip_box.left = std::max(crop_box.left, media_box.left);
81 clip_box.bottom = std::max(crop_box.bottom, media_box.bottom);
82 clip_box.right = std::min(crop_box.right, media_box.right);
83 clip_box.top = std::min(crop_box.top, media_box.top);
87 void ScalePdfRectangle(double scale_factor, PdfRectangle* rect) {
88 rect->left *= scale_factor;
89 rect->bottom *= scale_factor;
90 rect->right *= scale_factor;
91 rect->top *= scale_factor;
94 void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
95 const PdfRectangle& source_clip_box,
98 const float clip_box_width = source_clip_box.right - source_clip_box.left;
99 const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
101 // Center the intended clip region to real clip region.
102 *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
103 source_clip_box.left;
104 *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
105 source_clip_box.bottom;
108 void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect,
112 const PdfRectangle& source_clip_box,
115 // Align the intended clip region to left-top corner of real clip region.
118 *offset_x = -1 * source_clip_box.left;
119 *offset_y = page_height - source_clip_box.top;
123 *offset_y = -1 * source_clip_box.bottom;
126 *offset_x = page_width - source_clip_box.right;
130 *offset_x = page_height - source_clip_box.right;
131 *offset_y = page_width - source_clip_box.top;
139 } // namespace chrome_pdf