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"
7 #include "printing/units.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gfx/geometry/rect.h"
11 namespace chrome_pdf {
15 constexpr float kDefaultWidth = 8.5 * printing::kPointsPerInch;
16 constexpr float kDefaultHeight = 11.0 * printing::kPointsPerInch;
17 constexpr float kDefaultRatio = kDefaultWidth / kDefaultHeight;
18 constexpr double kTolerance = 0.0001;
20 void ExpectDefaultPortraitBox(const PdfRectangle& box) {
21 EXPECT_FLOAT_EQ(0, box.left);
22 EXPECT_FLOAT_EQ(0, box.bottom);
23 EXPECT_FLOAT_EQ(kDefaultWidth, box.right);
24 EXPECT_FLOAT_EQ(kDefaultHeight, box.top);
27 void ExpectDefaultLandscapeBox(const PdfRectangle& box) {
28 EXPECT_FLOAT_EQ(0, box.left);
29 EXPECT_FLOAT_EQ(0, box.bottom);
30 EXPECT_FLOAT_EQ(kDefaultHeight, box.right);
31 EXPECT_FLOAT_EQ(kDefaultWidth, box.top);
34 void ExpectBoxesAreEqual(const PdfRectangle& expected,
35 const PdfRectangle& actual) {
36 EXPECT_FLOAT_EQ(expected.left, actual.left);
37 EXPECT_FLOAT_EQ(expected.bottom, actual.bottom);
38 EXPECT_FLOAT_EQ(expected.right, actual.right);
39 EXPECT_FLOAT_EQ(expected.top, actual.top);
42 void InitializeBoxToInvalidValues(PdfRectangle* box) {
43 box->left = box->bottom = box->right = box->top = -1;
46 void InitializeBoxToDefaultPortraitValues(PdfRectangle* box) {
49 box->right = kDefaultWidth;
50 box->top = kDefaultHeight;
53 void InitializeBoxToDefaultLandscapeValue(PdfRectangle* box) {
56 box->right = kDefaultHeight;
57 box->top = kDefaultWidth;
62 TEST(PdfTransformTest, CalculateScaleFactor) {
63 gfx::Rect rect(kDefaultWidth, kDefaultHeight);
67 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
68 EXPECT_NEAR(1, scale, kTolerance);
69 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
70 EXPECT_NEAR(kDefaultRatio, scale, kTolerance);
73 rect = gfx::Rect(kDefaultWidth / 2, kDefaultHeight / 2);
74 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
75 EXPECT_NEAR(0.5, scale, kTolerance);
76 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
77 EXPECT_NEAR(kDefaultRatio / 2, scale, kTolerance);
80 rect = gfx::Rect(kDefaultWidth * 3, kDefaultHeight * 3);
81 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
82 EXPECT_NEAR(3, scale, kTolerance);
83 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
84 EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
87 rect = gfx::Rect(kDefaultHeight * 3, kDefaultWidth * 3);
88 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
89 EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
90 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
91 EXPECT_NEAR(3, scale, kTolerance);
94 rect = gfx::Rect(10, 1000);
95 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
96 EXPECT_NEAR(0.01634, scale, kTolerance);
97 scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
98 EXPECT_NEAR(0.01263, scale, kTolerance);
101 TEST(PdfTransformTest, SetDefaultClipBox) {
104 SetDefaultClipBox(false, &box);
105 ExpectDefaultPortraitBox(box);
107 SetDefaultClipBox(true, &box);
108 ExpectDefaultLandscapeBox(box);
111 TEST(PdfTransformTest, CalculateMediaBoxAndCropBox) {
112 PdfRectangle media_box;
113 PdfRectangle crop_box;
115 // Assume both boxes are there.
116 InitializeBoxToDefaultPortraitValues(&media_box);
117 InitializeBoxToDefaultLandscapeValue(&crop_box);
118 CalculateMediaBoxAndCropBox(true, true, true, &media_box, &crop_box);
119 ExpectDefaultPortraitBox(media_box);
120 ExpectDefaultLandscapeBox(crop_box);
122 // Assume both boxes are missing.
123 InitializeBoxToInvalidValues(&media_box);
124 InitializeBoxToInvalidValues(&crop_box);
125 CalculateMediaBoxAndCropBox(false, false, false, &media_box, &crop_box);
126 ExpectDefaultPortraitBox(media_box);
127 ExpectDefaultPortraitBox(crop_box);
128 CalculateMediaBoxAndCropBox(true, false, false, &media_box, &crop_box);
129 ExpectDefaultLandscapeBox(media_box);
130 ExpectDefaultLandscapeBox(crop_box);
132 // Assume crop box is missing.
133 constexpr PdfRectangle expected_box = {0, 0, 42, 420};
134 media_box = expected_box;
135 InitializeBoxToInvalidValues(&crop_box);
136 CalculateMediaBoxAndCropBox(false, true, false, &media_box, &crop_box);
137 ExpectBoxesAreEqual(expected_box, media_box);
138 ExpectBoxesAreEqual(expected_box, crop_box);
140 // Assume media box is missing.
141 InitializeBoxToInvalidValues(&media_box);
142 CalculateMediaBoxAndCropBox(false, false, true, &media_box, &crop_box);
143 ExpectBoxesAreEqual(expected_box, media_box);
144 ExpectBoxesAreEqual(expected_box, crop_box);
147 TEST(PdfTransformTest, CalculateClipBoxBoundary) {
148 PdfRectangle media_box;
149 PdfRectangle crop_box;
152 // media box and crop box are the same.
153 InitializeBoxToDefaultPortraitValues(&media_box);
154 InitializeBoxToDefaultPortraitValues(&crop_box);
155 result = CalculateClipBoxBoundary(media_box, crop_box);
156 ExpectDefaultPortraitBox(result);
158 // media box is portrait and crop box is landscape.
159 InitializeBoxToDefaultLandscapeValue(&crop_box);
160 result = CalculateClipBoxBoundary(media_box, crop_box);
161 EXPECT_FLOAT_EQ(0, result.left);
162 EXPECT_FLOAT_EQ(0, result.bottom);
163 EXPECT_FLOAT_EQ(kDefaultWidth, result.right);
164 EXPECT_FLOAT_EQ(kDefaultWidth, result.top);
166 // crop box is smaller than media box.
169 crop_box.right = 100;
171 result = CalculateClipBoxBoundary(media_box, crop_box);
172 EXPECT_FLOAT_EQ(0, result.left);
173 EXPECT_FLOAT_EQ(0, result.bottom);
174 EXPECT_FLOAT_EQ(100, result.right);
175 EXPECT_FLOAT_EQ(200, result.top);
177 // crop box is smaller than the media box in one dimension and longer in the
181 crop_box.right = 100;
183 result = CalculateClipBoxBoundary(media_box, crop_box);
184 EXPECT_FLOAT_EQ(0, result.left);
185 EXPECT_FLOAT_EQ(0, result.bottom);
186 EXPECT_FLOAT_EQ(100, result.right);
187 EXPECT_FLOAT_EQ(kDefaultHeight, result.top);
190 TEST(PdfTransformTest, CalculateScaledClipBoxOffset) {
191 constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
192 PdfRectangle clip_box;
196 // |rect| and |clip_box| are the same size.
197 InitializeBoxToDefaultPortraitValues(&clip_box);
198 CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
199 EXPECT_DOUBLE_EQ(0, offset_x);
200 EXPECT_DOUBLE_EQ(0, offset_y);
202 // |rect| is larger than |clip_box|.
205 CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
206 EXPECT_DOUBLE_EQ(229.5, offset_x);
207 EXPECT_DOUBLE_EQ(198, offset_y);
210 TEST(PdfTransformTest, CalculateNonScaledClipBoxOffset) {
211 int page_width = kDefaultWidth;
212 int page_height = kDefaultHeight;
213 constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
214 PdfRectangle clip_box;
218 // |rect|, page size and |clip_box| are the same.
219 InitializeBoxToDefaultPortraitValues(&clip_box);
220 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
221 &offset_x, &offset_y);
222 EXPECT_DOUBLE_EQ(0, offset_x);
223 EXPECT_DOUBLE_EQ(0, offset_y);
224 CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
225 &offset_x, &offset_y);
226 EXPECT_DOUBLE_EQ(0, offset_x);
227 EXPECT_DOUBLE_EQ(0, offset_y);
228 CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
229 &offset_x, &offset_y);
230 EXPECT_DOUBLE_EQ(0, offset_x);
231 EXPECT_DOUBLE_EQ(0, offset_y);
232 CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
233 &offset_x, &offset_y);
234 EXPECT_DOUBLE_EQ(180, offset_x);
235 EXPECT_DOUBLE_EQ(-180, offset_y);
237 // Smaller |clip_box|.
240 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
241 &offset_x, &offset_y);
242 EXPECT_DOUBLE_EQ(0, offset_x);
243 EXPECT_DOUBLE_EQ(594, offset_y);
244 CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
245 &offset_x, &offset_y);
246 EXPECT_DOUBLE_EQ(0, offset_x);
247 EXPECT_DOUBLE_EQ(0, offset_y);
248 CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
249 &offset_x, &offset_y);
250 EXPECT_DOUBLE_EQ(306, offset_x);
251 EXPECT_DOUBLE_EQ(0, offset_y);
252 CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
253 &offset_x, &offset_y);
254 EXPECT_DOUBLE_EQ(486, offset_x);
255 EXPECT_DOUBLE_EQ(414, offset_y);
258 InitializeBoxToDefaultPortraitValues(&clip_box);
261 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
262 &offset_x, &offset_y);
263 EXPECT_DOUBLE_EQ(0, offset_x);
264 EXPECT_DOUBLE_EQ(20, offset_y);
265 CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
266 &offset_x, &offset_y);
267 EXPECT_DOUBLE_EQ(0, offset_x);
268 EXPECT_DOUBLE_EQ(0, offset_y);
269 CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
270 &offset_x, &offset_y);
271 EXPECT_DOUBLE_EQ(10, offset_x);
272 EXPECT_DOUBLE_EQ(0, offset_y);
273 CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
274 &offset_x, &offset_y);
275 EXPECT_DOUBLE_EQ(200, offset_x);
276 EXPECT_DOUBLE_EQ(-170, offset_y);
279 // https://crbug.com/491160 and https://crbug.com/588757
280 TEST(PdfTransformTest, ReversedMediaBox) {
281 int page_width = kDefaultWidth;
282 int page_height = kDefaultHeight;
283 constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
284 PdfRectangle clip_box;
288 constexpr PdfRectangle expected_media_box_b491160 = {0, -792, 612, 0};
289 PdfRectangle media_box_b491160 = {0, 0, 612, -792};
290 CalculateMediaBoxAndCropBox(false, true, false, &media_box_b491160,
292 ExpectBoxesAreEqual(expected_media_box_b491160, media_box_b491160);
293 ExpectBoxesAreEqual(expected_media_box_b491160, clip_box);
295 CalculateScaledClipBoxOffset(rect, media_box_b491160, &offset_x, &offset_y);
296 EXPECT_DOUBLE_EQ(0, offset_x);
297 EXPECT_DOUBLE_EQ(792, offset_y);
299 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height,
300 media_box_b491160, &offset_x, &offset_y);
301 EXPECT_DOUBLE_EQ(0, offset_x);
302 EXPECT_DOUBLE_EQ(792, offset_y);
304 PdfRectangle media_box_b588757 = {0, 792, 612, 0};
305 CalculateMediaBoxAndCropBox(false, true, false, &media_box_b588757,
307 ExpectDefaultPortraitBox(media_box_b588757);
308 ExpectDefaultPortraitBox(clip_box);
310 CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
311 EXPECT_DOUBLE_EQ(0, offset_x);
312 EXPECT_DOUBLE_EQ(0, offset_y);
314 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
315 &offset_x, &offset_y);
316 EXPECT_DOUBLE_EQ(0, offset_x);
317 EXPECT_DOUBLE_EQ(0, offset_y);
319 PdfRectangle media_box_left_right_flipped = {612, 792, 0, 0};
320 CalculateMediaBoxAndCropBox(false, true, false, &media_box_left_right_flipped,
322 ExpectDefaultPortraitBox(media_box_left_right_flipped);
323 ExpectDefaultPortraitBox(clip_box);
325 CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
326 EXPECT_DOUBLE_EQ(0, offset_x);
327 EXPECT_DOUBLE_EQ(0, offset_y);
329 CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
330 &offset_x, &offset_y);
331 EXPECT_DOUBLE_EQ(0, offset_x);
332 EXPECT_DOUBLE_EQ(0, offset_y);
335 } // namespace chrome_pdf