thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 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. |
| 4 | |
Lei Zhang | cc9acc1 | 2018-03-05 20:49:13 | [diff] [blame] | 5 | #include "pdf/pdf_transform.h" |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 6 | |
| 7 | #include <algorithm> |
Lei Zhang | cc9acc1 | 2018-03-05 20:49:13 | [diff] [blame] | 8 | #include <utility> |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 9 | |
Hans Wennborg | 5078d10 | 2020-04-29 18:26:46 | [diff] [blame] | 10 | #include "base/notreached.h" |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 11 | #include "ui/gfx/geometry/point_f.h" |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 12 | #include "ui/gfx/geometry/rect.h" |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 13 | #include "ui/gfx/geometry/size_f.h" |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 14 | |
Lei Zhang | cc9acc1 | 2018-03-05 20:49:13 | [diff] [blame] | 15 | namespace chrome_pdf { |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 16 | |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 17 | namespace { |
| 18 | |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 19 | // When a PdfRectangle has top < bottom, or right < left, the values should be |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 20 | // swapped. |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 21 | void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) { |
| 22 | if (rect->top < rect->bottom) |
| 23 | std::swap(rect->top, rect->bottom); |
| 24 | if (rect->right < rect->left) |
| 25 | std::swap(rect->right, rect->left); |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | } // namespace |
| 29 | |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 30 | float CalculateScaleFactor(const gfx::Rect& content_rect, |
| 31 | const gfx::SizeF& src_size, |
| 32 | bool rotated) { |
| 33 | if (src_size.IsEmpty()) |
| 34 | return 1.0f; |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 35 | |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 36 | float actual_source_page_width = |
| 37 | rotated ? src_size.height() : src_size.width(); |
| 38 | float actual_source_page_height = |
| 39 | rotated ? src_size.width() : src_size.height(); |
| 40 | float ratio_x = content_rect.width() / actual_source_page_width; |
| 41 | float ratio_y = content_rect.height() / actual_source_page_height; |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 42 | return std::min(ratio_x, ratio_y); |
| 43 | } |
| 44 | |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 45 | void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) { |
Henrique Nakashima | 1c5da8e | 2018-10-05 21:56:43 | [diff] [blame] | 46 | constexpr int kDpi = 72; |
| 47 | constexpr float kPaperWidth = 8.5 * kDpi; |
| 48 | constexpr float kPaperHeight = 11 * kDpi; |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 49 | clip_box->left = 0; |
| 50 | clip_box->bottom = 0; |
| 51 | clip_box->right = rotated ? kPaperHeight : kPaperWidth; |
| 52 | clip_box->top = rotated ? kPaperWidth : kPaperHeight; |
| 53 | } |
| 54 | |
| 55 | void CalculateMediaBoxAndCropBox(bool rotated, |
| 56 | bool has_media_box, |
| 57 | bool has_crop_box, |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 58 | PdfRectangle* media_box, |
| 59 | PdfRectangle* crop_box) { |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 60 | if (has_media_box) |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 61 | SwapPdfRectangleValuesIfNeeded(media_box); |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 62 | if (has_crop_box) |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 63 | SwapPdfRectangleValuesIfNeeded(crop_box); |
thestig | b923f18 | 2016-04-05 00:23:33 | [diff] [blame] | 64 | |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 65 | if (!has_media_box && !has_crop_box) { |
| 66 | SetDefaultClipBox(rotated, crop_box); |
| 67 | SetDefaultClipBox(rotated, media_box); |
| 68 | } else if (has_crop_box && !has_media_box) { |
| 69 | *media_box = *crop_box; |
| 70 | } else if (has_media_box && !has_crop_box) { |
| 71 | *crop_box = *media_box; |
| 72 | } |
| 73 | } |
| 74 | |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 75 | PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box, |
| 76 | const PdfRectangle& crop_box) { |
| 77 | PdfRectangle clip_box; |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 78 | |
Daniel Hosseinian | e257d96 | 2021-04-23 21:18:35 | [diff] [blame] | 79 | // Clip `media_box` to the size of `crop_box`, but ignore `crop_box` if it is |
| 80 | // bigger than `media_box`. |
krb | 8f981ab | 2016-03-14 14:37:44 | [diff] [blame] | 81 | clip_box.left = std::max(crop_box.left, media_box.left); |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 82 | clip_box.bottom = std::max(crop_box.bottom, media_box.bottom); |
krb | 8f981ab | 2016-03-14 14:37:44 | [diff] [blame] | 83 | clip_box.right = std::min(crop_box.right, media_box.right); |
| 84 | clip_box.top = std::min(crop_box.top, media_box.top); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 85 | return clip_box; |
| 86 | } |
| 87 | |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 88 | void ScalePdfRectangle(float scale_factor, PdfRectangle* rect) { |
thestig | 09649fa | 2016-04-13 03:26:49 | [diff] [blame] | 89 | rect->left *= scale_factor; |
| 90 | rect->bottom *= scale_factor; |
| 91 | rect->right *= scale_factor; |
| 92 | rect->top *= scale_factor; |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 93 | } |
| 94 | |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 95 | gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect, |
| 96 | const PdfRectangle& source_clip_box) { |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 97 | const float clip_box_width = source_clip_box.right - source_clip_box.left; |
| 98 | const float clip_box_height = source_clip_box.top - source_clip_box.bottom; |
| 99 | |
| 100 | // Center the intended clip region to real clip region. |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 101 | return gfx::PointF((content_rect.width() - clip_box_width) / 2 + |
| 102 | content_rect.x() - source_clip_box.left, |
| 103 | (content_rect.height() - clip_box_height) / 2 + |
| 104 | content_rect.y() - source_clip_box.bottom); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 105 | } |
| 106 | |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 107 | gfx::PointF CalculateNonScaledClipBoxOffset( |
| 108 | int rotation, |
| 109 | int page_width, |
| 110 | int page_height, |
| 111 | const PdfRectangle& source_clip_box) { |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 112 | // Align the intended clip region to left-top corner of real clip region. |
| 113 | switch (rotation) { |
| 114 | case 0: |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 115 | return gfx::PointF(-1 * source_clip_box.left, |
| 116 | page_height - source_clip_box.top); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 117 | case 1: |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 118 | return gfx::PointF(0, -1 * source_clip_box.bottom); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 119 | case 2: |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 120 | return gfx::PointF(page_width - source_clip_box.right, 0); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 121 | case 3: |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 122 | return gfx::PointF(page_height - source_clip_box.right, |
| 123 | page_width - source_clip_box.top); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 124 | default: |
| 125 | NOTREACHED(); |
Lei Zhang | 63443b20 | 2019-12-10 23:59:35 | [diff] [blame] | 126 | return gfx::PointF(); |
thestig | 64c8e26 | 2015-10-28 19:04:26 | [diff] [blame] | 127 | } |
| 128 | } |
| 129 | |
Lei Zhang | cc9acc1 | 2018-03-05 20:49:13 | [diff] [blame] | 130 | } // namespace chrome_pdf |