Upload upstream chromium 76.0.3809.146
[platform/framework/web/chromium-efl.git] / pdf / pdf_transform.cc
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
5 #include "pdf/pdf_transform.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/logging.h"
11 #include "ui/gfx/geometry/rect.h"
12
13 namespace chrome_pdf {
14
15 namespace {
16
17 // When a PdfRectangle has top < bottom, or right < left, the values should be
18 // swapped.
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);
24 }
25
26 }  // namespace
27
28 double CalculateScaleFactor(const gfx::Rect& content_rect,
29                             double src_width,
30                             double src_height,
31                             bool rotated) {
32   if (src_width == 0 || src_height == 0)
33     return 1.0;
34
35   double actual_source_page_width = rotated ? src_height : src_width;
36   double actual_source_page_height = rotated ? src_width : src_height;
37   double ratio_x =
38       static_cast<double>(content_rect.width()) / actual_source_page_width;
39   double ratio_y =
40       static_cast<double>(content_rect.height()) / actual_source_page_height;
41   return std::min(ratio_x, ratio_y);
42 }
43
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;
48   clip_box->left = 0;
49   clip_box->bottom = 0;
50   clip_box->right = rotated ? kPaperHeight : kPaperWidth;
51   clip_box->top = rotated ? kPaperWidth : kPaperHeight;
52 }
53
54 void CalculateMediaBoxAndCropBox(bool rotated,
55                                  bool has_media_box,
56                                  bool has_crop_box,
57                                  PdfRectangle* media_box,
58                                  PdfRectangle* crop_box) {
59   if (has_media_box)
60     SwapPdfRectangleValuesIfNeeded(media_box);
61   if (has_crop_box)
62     SwapPdfRectangleValuesIfNeeded(crop_box);
63
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;
71   }
72 }
73
74 PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
75                                       const PdfRectangle& crop_box) {
76   PdfRectangle clip_box;
77
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);
84   return clip_box;
85 }
86
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;
92 }
93
94 void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
95                                   const PdfRectangle& source_clip_box,
96                                   double* offset_x,
97                                   double* offset_y) {
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;
100
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;
106 }
107
108 void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect,
109                                      int rotation,
110                                      int page_width,
111                                      int page_height,
112                                      const PdfRectangle& source_clip_box,
113                                      double* offset_x,
114                                      double* offset_y) {
115   // Align the intended clip region to left-top corner of real clip region.
116   switch (rotation) {
117     case 0:
118       *offset_x = -1 * source_clip_box.left;
119       *offset_y = page_height - source_clip_box.top;
120       break;
121     case 1:
122       *offset_x = 0;
123       *offset_y = -1 * source_clip_box.bottom;
124       break;
125     case 2:
126       *offset_x = page_width - source_clip_box.right;
127       *offset_y = 0;
128       break;
129     case 3:
130       *offset_x = page_height - source_clip_box.right;
131       *offset_y = page_width - source_clip_box.top;
132       break;
133     default:
134       NOTREACHED();
135       break;
136   }
137 }
138
139 }  // namespace chrome_pdf