blob: a8cac8bbce39178439e92eb5602a596aa68e5eca [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281// Copyright 2015 The Chromium Authors
thestig64c8e262015-10-28 19:04:262// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Lei Zhangcc9acc12018-03-05 20:49:135#include "pdf/pdf_transform.h"
thestig64c8e262015-10-28 19:04:266
7#include "printing/units.h"
8#include "testing/gtest/include/gtest/gtest.h"
Lei Zhang63443b202019-12-10 23:59:359#include "ui/gfx/geometry/point_f.h"
thestig64c8e262015-10-28 19:04:2610#include "ui/gfx/geometry/rect.h"
Lei Zhang63443b202019-12-10 23:59:3511#include "ui/gfx/geometry/size_f.h"
thestig64c8e262015-10-28 19:04:2612
Lei Zhangcc9acc12018-03-05 20:49:1313namespace chrome_pdf {
thestig64c8e262015-10-28 19:04:2614
15namespace {
16
Henrique Nakashima1c5da8e2018-10-05 21:56:4317constexpr float kDefaultWidth = 8.5 * printing::kPointsPerInch;
18constexpr float kDefaultHeight = 11.0 * printing::kPointsPerInch;
19constexpr float kDefaultRatio = kDefaultWidth / kDefaultHeight;
Lei Zhang63443b202019-12-10 23:59:3520constexpr float kTolerance = 0.0001f;
thestig64c8e262015-10-28 19:04:2621
thestig09649fa2016-04-13 03:26:4922void ExpectDefaultPortraitBox(const PdfRectangle& box) {
thestig64c8e262015-10-28 19:04:2623 EXPECT_FLOAT_EQ(0, box.left);
thestig09649fa2016-04-13 03:26:4924 EXPECT_FLOAT_EQ(0, box.bottom);
thestig64c8e262015-10-28 19:04:2625 EXPECT_FLOAT_EQ(kDefaultWidth, box.right);
26 EXPECT_FLOAT_EQ(kDefaultHeight, box.top);
thestig64c8e262015-10-28 19:04:2627}
28
thestig09649fa2016-04-13 03:26:4929void ExpectDefaultLandscapeBox(const PdfRectangle& box) {
thestig64c8e262015-10-28 19:04:2630 EXPECT_FLOAT_EQ(0, box.left);
thestig09649fa2016-04-13 03:26:4931 EXPECT_FLOAT_EQ(0, box.bottom);
thestig64c8e262015-10-28 19:04:2632 EXPECT_FLOAT_EQ(kDefaultHeight, box.right);
33 EXPECT_FLOAT_EQ(kDefaultWidth, box.top);
thestig64c8e262015-10-28 19:04:2634}
35
thestig09649fa2016-04-13 03:26:4936void ExpectBoxesAreEqual(const PdfRectangle& expected,
37 const PdfRectangle& actual) {
thestig64c8e262015-10-28 19:04:2638 EXPECT_FLOAT_EQ(expected.left, actual.left);
thestig09649fa2016-04-13 03:26:4939 EXPECT_FLOAT_EQ(expected.bottom, actual.bottom);
thestig64c8e262015-10-28 19:04:2640 EXPECT_FLOAT_EQ(expected.right, actual.right);
41 EXPECT_FLOAT_EQ(expected.top, actual.top);
thestig64c8e262015-10-28 19:04:2642}
43
thestig09649fa2016-04-13 03:26:4944void InitializeBoxToInvalidValues(PdfRectangle* box) {
45 box->left = box->bottom = box->right = box->top = -1;
thestig64c8e262015-10-28 19:04:2646}
47
thestig09649fa2016-04-13 03:26:4948void InitializeBoxToDefaultPortraitValues(PdfRectangle* box) {
thestig64c8e262015-10-28 19:04:2649 box->left = 0;
thestig09649fa2016-04-13 03:26:4950 box->bottom = 0;
thestig64c8e262015-10-28 19:04:2651 box->right = kDefaultWidth;
52 box->top = kDefaultHeight;
thestig64c8e262015-10-28 19:04:2653}
54
thestig09649fa2016-04-13 03:26:4955void InitializeBoxToDefaultLandscapeValue(PdfRectangle* box) {
thestig64c8e262015-10-28 19:04:2656 box->left = 0;
thestig09649fa2016-04-13 03:26:4957 box->bottom = 0;
thestig64c8e262015-10-28 19:04:2658 box->right = kDefaultHeight;
59 box->top = kDefaultWidth;
thestig64c8e262015-10-28 19:04:2660}
61
62} // namespace
63
64TEST(PdfTransformTest, CalculateScaleFactor) {
Lei Zhang63443b202019-12-10 23:59:3565 static constexpr gfx::SizeF kSize(kDefaultWidth, kDefaultHeight);
thestig64c8e262015-10-28 19:04:2666 gfx::Rect rect(kDefaultWidth, kDefaultHeight);
Lei Zhang63443b202019-12-10 23:59:3567 float scale;
thestig64c8e262015-10-28 19:04:2668
69 // 1:1
Lei Zhang63443b202019-12-10 23:59:3570 scale = CalculateScaleFactor(rect, kSize, false);
71 EXPECT_NEAR(1.0f, scale, kTolerance);
72 scale = CalculateScaleFactor(rect, kSize, true);
thestig64c8e262015-10-28 19:04:2673 EXPECT_NEAR(kDefaultRatio, scale, kTolerance);
74
75 // 1:2
76 rect = gfx::Rect(kDefaultWidth / 2, kDefaultHeight / 2);
Lei Zhang63443b202019-12-10 23:59:3577 scale = CalculateScaleFactor(rect, kSize, false);
78 EXPECT_NEAR(0.5f, scale, kTolerance);
79 scale = CalculateScaleFactor(rect, kSize, true);
thestig64c8e262015-10-28 19:04:2680 EXPECT_NEAR(kDefaultRatio / 2, scale, kTolerance);
81
82 // 3:1
83 rect = gfx::Rect(kDefaultWidth * 3, kDefaultHeight * 3);
Lei Zhang63443b202019-12-10 23:59:3584 scale = CalculateScaleFactor(rect, kSize, false);
85 EXPECT_NEAR(3.0f, scale, kTolerance);
86 scale = CalculateScaleFactor(rect, kSize, true);
thestig64c8e262015-10-28 19:04:2687 EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
88
89 // 3:1, rotated.
90 rect = gfx::Rect(kDefaultHeight * 3, kDefaultWidth * 3);
Lei Zhang63443b202019-12-10 23:59:3591 scale = CalculateScaleFactor(rect, kSize, false);
thestig64c8e262015-10-28 19:04:2692 EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
Lei Zhang63443b202019-12-10 23:59:3593 scale = CalculateScaleFactor(rect, kSize, true);
94 EXPECT_NEAR(3.0f, scale, kTolerance);
thestig64c8e262015-10-28 19:04:2695
96 // Odd size
97 rect = gfx::Rect(10, 1000);
Lei Zhang63443b202019-12-10 23:59:3598 scale = CalculateScaleFactor(rect, kSize, false);
99 EXPECT_NEAR(0.01634f, scale, kTolerance);
100 scale = CalculateScaleFactor(rect, kSize, true);
101 EXPECT_NEAR(0.01263f, scale, kTolerance);
thestig64c8e262015-10-28 19:04:26102}
103
104TEST(PdfTransformTest, SetDefaultClipBox) {
thestig09649fa2016-04-13 03:26:49105 PdfRectangle box;
thestig64c8e262015-10-28 19:04:26106
107 SetDefaultClipBox(false, &box);
108 ExpectDefaultPortraitBox(box);
109
110 SetDefaultClipBox(true, &box);
111 ExpectDefaultLandscapeBox(box);
112}
113
114TEST(PdfTransformTest, CalculateMediaBoxAndCropBox) {
thestig09649fa2016-04-13 03:26:49115 PdfRectangle media_box;
116 PdfRectangle crop_box;
thestig64c8e262015-10-28 19:04:26117
118 // Assume both boxes are there.
119 InitializeBoxToDefaultPortraitValues(&media_box);
120 InitializeBoxToDefaultLandscapeValue(&crop_box);
121 CalculateMediaBoxAndCropBox(true, true, true, &media_box, &crop_box);
122 ExpectDefaultPortraitBox(media_box);
123 ExpectDefaultLandscapeBox(crop_box);
124
125 // Assume both boxes are missing.
126 InitializeBoxToInvalidValues(&media_box);
127 InitializeBoxToInvalidValues(&crop_box);
128 CalculateMediaBoxAndCropBox(false, false, false, &media_box, &crop_box);
129 ExpectDefaultPortraitBox(media_box);
130 ExpectDefaultPortraitBox(crop_box);
131 CalculateMediaBoxAndCropBox(true, false, false, &media_box, &crop_box);
132 ExpectDefaultLandscapeBox(media_box);
133 ExpectDefaultLandscapeBox(crop_box);
134
135 // Assume crop box is missing.
Henrique Nakashima1c5da8e2018-10-05 21:56:43136 constexpr PdfRectangle expected_box = {0, 0, 42, 420};
thestig64c8e262015-10-28 19:04:26137 media_box = expected_box;
138 InitializeBoxToInvalidValues(&crop_box);
139 CalculateMediaBoxAndCropBox(false, true, false, &media_box, &crop_box);
140 ExpectBoxesAreEqual(expected_box, media_box);
141 ExpectBoxesAreEqual(expected_box, crop_box);
142
143 // Assume media box is missing.
144 InitializeBoxToInvalidValues(&media_box);
145 CalculateMediaBoxAndCropBox(false, false, true, &media_box, &crop_box);
146 ExpectBoxesAreEqual(expected_box, media_box);
147 ExpectBoxesAreEqual(expected_box, crop_box);
148}
149
150TEST(PdfTransformTest, CalculateClipBoxBoundary) {
thestig09649fa2016-04-13 03:26:49151 PdfRectangle media_box;
152 PdfRectangle crop_box;
153 PdfRectangle result;
thestig64c8e262015-10-28 19:04:26154
155 // media box and crop box are the same.
156 InitializeBoxToDefaultPortraitValues(&media_box);
157 InitializeBoxToDefaultPortraitValues(&crop_box);
158 result = CalculateClipBoxBoundary(media_box, crop_box);
159 ExpectDefaultPortraitBox(result);
160
161 // media box is portrait and crop box is landscape.
162 InitializeBoxToDefaultLandscapeValue(&crop_box);
163 result = CalculateClipBoxBoundary(media_box, crop_box);
164 EXPECT_FLOAT_EQ(0, result.left);
thestig09649fa2016-04-13 03:26:49165 EXPECT_FLOAT_EQ(0, result.bottom);
thestig64c8e262015-10-28 19:04:26166 EXPECT_FLOAT_EQ(kDefaultWidth, result.right);
167 EXPECT_FLOAT_EQ(kDefaultWidth, result.top);
thestig64c8e262015-10-28 19:04:26168
169 // crop box is smaller than media box.
170 crop_box.left = 0;
thestig64c8e262015-10-28 19:04:26171 crop_box.bottom = 0;
thestig09649fa2016-04-13 03:26:49172 crop_box.right = 100;
thestig64c8e262015-10-28 19:04:26173 crop_box.top = 200;
174 result = CalculateClipBoxBoundary(media_box, crop_box);
175 EXPECT_FLOAT_EQ(0, result.left);
thestig09649fa2016-04-13 03:26:49176 EXPECT_FLOAT_EQ(0, result.bottom);
thestig64c8e262015-10-28 19:04:26177 EXPECT_FLOAT_EQ(100, result.right);
178 EXPECT_FLOAT_EQ(200, result.top);
thestig64c8e262015-10-28 19:04:26179
180 // crop box is smaller than the media box in one dimension and longer in the
181 // other.
182 crop_box.left = 0;
thestig64c8e262015-10-28 19:04:26183 crop_box.bottom = 0;
thestig09649fa2016-04-13 03:26:49184 crop_box.right = 100;
thestig64c8e262015-10-28 19:04:26185 crop_box.top = 2000;
186 result = CalculateClipBoxBoundary(media_box, crop_box);
187 EXPECT_FLOAT_EQ(0, result.left);
thestig09649fa2016-04-13 03:26:49188 EXPECT_FLOAT_EQ(0, result.bottom);
thestig64c8e262015-10-28 19:04:26189 EXPECT_FLOAT_EQ(100, result.right);
190 EXPECT_FLOAT_EQ(kDefaultHeight, result.top);
thestig64c8e262015-10-28 19:04:26191}
192
193TEST(PdfTransformTest, CalculateScaledClipBoxOffset) {
Henrique Nakashima1c5da8e2018-10-05 21:56:43194 constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
thestig09649fa2016-04-13 03:26:49195 PdfRectangle clip_box;
Lei Zhang63443b202019-12-10 23:59:35196 gfx::PointF offset;
thestig64c8e262015-10-28 19:04:26197
Daniel Hosseiniane257d962021-04-23 21:18:35198 // `rect` and `clip_box` are the same size.
thestig64c8e262015-10-28 19:04:26199 InitializeBoxToDefaultPortraitValues(&clip_box);
Lei Zhang63443b202019-12-10 23:59:35200 offset = CalculateScaledClipBoxOffset(rect, clip_box);
201 EXPECT_FLOAT_EQ(0, offset.x());
202 EXPECT_FLOAT_EQ(0, offset.y());
thestig64c8e262015-10-28 19:04:26203
Daniel Hosseiniane257d962021-04-23 21:18:35204 // `rect` is larger than `clip_box`.
thestig64c8e262015-10-28 19:04:26205 clip_box.top /= 2;
206 clip_box.right /= 4;
Lei Zhang63443b202019-12-10 23:59:35207 offset = CalculateScaledClipBoxOffset(rect, clip_box);
208 EXPECT_FLOAT_EQ(229.5f, offset.x());
209 EXPECT_FLOAT_EQ(198, offset.y());
thestig64c8e262015-10-28 19:04:26210}
211
212TEST(PdfTransformTest, CalculateNonScaledClipBoxOffset) {
213 int page_width = kDefaultWidth;
214 int page_height = kDefaultHeight;
thestig09649fa2016-04-13 03:26:49215 PdfRectangle clip_box;
Lei Zhang63443b202019-12-10 23:59:35216 gfx::PointF offset;
thestig64c8e262015-10-28 19:04:26217
Daniel Hosseiniane257d962021-04-23 21:18:35218 // `rect`, page size and `clip_box` are the same.
thestig64c8e262015-10-28 19:04:26219 InitializeBoxToDefaultPortraitValues(&clip_box);
Lei Zhang63443b202019-12-10 23:59:35220 offset =
221 CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
222 EXPECT_FLOAT_EQ(0, offset.x());
223 EXPECT_FLOAT_EQ(0, offset.y());
224 offset =
225 CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
226 EXPECT_FLOAT_EQ(0, offset.x());
227 EXPECT_FLOAT_EQ(0, offset.y());
228 offset =
229 CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
230 EXPECT_FLOAT_EQ(0, offset.x());
231 EXPECT_FLOAT_EQ(0, offset.y());
232 offset =
233 CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
234 EXPECT_FLOAT_EQ(180, offset.x());
235 EXPECT_FLOAT_EQ(-180, offset.y());
thestig64c8e262015-10-28 19:04:26236
Daniel Hosseiniane257d962021-04-23 21:18:35237 // Smaller `clip_box`.
thestig64c8e262015-10-28 19:04:26238 clip_box.top /= 4;
239 clip_box.right /= 2;
Lei Zhang63443b202019-12-10 23:59:35240 offset =
241 CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
242 EXPECT_FLOAT_EQ(0, offset.x());
243 EXPECT_FLOAT_EQ(594, offset.y());
244 offset =
245 CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
246 EXPECT_FLOAT_EQ(0, offset.x());
247 EXPECT_FLOAT_EQ(0, offset.y());
248 offset =
249 CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
250 EXPECT_FLOAT_EQ(306, offset.x());
251 EXPECT_FLOAT_EQ(0, offset.y());
252 offset =
253 CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
254 EXPECT_FLOAT_EQ(486, offset.x());
255 EXPECT_FLOAT_EQ(414, offset.y());
thestig64c8e262015-10-28 19:04:26256
257 // Larger page size.
258 InitializeBoxToDefaultPortraitValues(&clip_box);
259 page_width += 10;
260 page_height += 20;
Lei Zhang63443b202019-12-10 23:59:35261 offset =
262 CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
263 EXPECT_FLOAT_EQ(0, offset.x());
264 EXPECT_FLOAT_EQ(20, offset.y());
265 offset =
266 CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
267 EXPECT_FLOAT_EQ(0, offset.x());
268 EXPECT_FLOAT_EQ(0, offset.y());
269 offset =
270 CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
271 EXPECT_FLOAT_EQ(10, offset.x());
272 EXPECT_FLOAT_EQ(0, offset.y());
273 offset =
274 CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
275 EXPECT_FLOAT_EQ(200, offset.x());
276 EXPECT_FLOAT_EQ(-170, offset.y());
thestig64c8e262015-10-28 19:04:26277}
278
thestigb923f182016-04-05 00:23:33279// https://crbug.com/491160 and https://crbug.com/588757
280TEST(PdfTransformTest, ReversedMediaBox) {
281 int page_width = kDefaultWidth;
282 int page_height = kDefaultHeight;
Henrique Nakashima1c5da8e2018-10-05 21:56:43283 constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
thestig09649fa2016-04-13 03:26:49284 PdfRectangle clip_box;
Lei Zhang63443b202019-12-10 23:59:35285 gfx::PointF offset;
thestigb923f182016-04-05 00:23:33286
Henrique Nakashima1c5da8e2018-10-05 21:56:43287 constexpr PdfRectangle expected_media_box_b491160 = {0, -792, 612, 0};
thestig09649fa2016-04-13 03:26:49288 PdfRectangle media_box_b491160 = {0, 0, 612, -792};
thestigb923f182016-04-05 00:23:33289 CalculateMediaBoxAndCropBox(false, true, false, &media_box_b491160,
290 &clip_box);
291 ExpectBoxesAreEqual(expected_media_box_b491160, media_box_b491160);
292 ExpectBoxesAreEqual(expected_media_box_b491160, clip_box);
293
Lei Zhang63443b202019-12-10 23:59:35294 offset = CalculateScaledClipBoxOffset(rect, media_box_b491160);
295 EXPECT_FLOAT_EQ(0, offset.x());
296 EXPECT_FLOAT_EQ(792, offset.y());
thestigb923f182016-04-05 00:23:33297
Lei Zhang63443b202019-12-10 23:59:35298 offset = CalculateNonScaledClipBoxOffset(0, page_width, page_height,
299 media_box_b491160);
300 EXPECT_FLOAT_EQ(0, offset.x());
301 EXPECT_FLOAT_EQ(792, offset.y());
thestigb923f182016-04-05 00:23:33302
thestig09649fa2016-04-13 03:26:49303 PdfRectangle media_box_b588757 = {0, 792, 612, 0};
thestigb923f182016-04-05 00:23:33304 CalculateMediaBoxAndCropBox(false, true, false, &media_box_b588757,
305 &clip_box);
306 ExpectDefaultPortraitBox(media_box_b588757);
307 ExpectDefaultPortraitBox(clip_box);
308
Lei Zhang63443b202019-12-10 23:59:35309 offset = CalculateScaledClipBoxOffset(rect, clip_box);
310 EXPECT_FLOAT_EQ(0, offset.x());
311 EXPECT_FLOAT_EQ(0, offset.y());
thestigb923f182016-04-05 00:23:33312
Lei Zhang63443b202019-12-10 23:59:35313 offset =
314 CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
315 EXPECT_FLOAT_EQ(0, offset.x());
316 EXPECT_FLOAT_EQ(0, offset.y());
thestigb923f182016-04-05 00:23:33317
thestig09649fa2016-04-13 03:26:49318 PdfRectangle media_box_left_right_flipped = {612, 792, 0, 0};
thestigb923f182016-04-05 00:23:33319 CalculateMediaBoxAndCropBox(false, true, false, &media_box_left_right_flipped,
320 &clip_box);
321 ExpectDefaultPortraitBox(media_box_left_right_flipped);
322 ExpectDefaultPortraitBox(clip_box);
323
Lei Zhang63443b202019-12-10 23:59:35324 offset = CalculateScaledClipBoxOffset(rect, clip_box);
325 EXPECT_FLOAT_EQ(0, offset.x());
326 EXPECT_FLOAT_EQ(0, offset.y());
thestigb923f182016-04-05 00:23:33327
Lei Zhang63443b202019-12-10 23:59:35328 offset =
329 CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
330 EXPECT_FLOAT_EQ(0, offset.x());
331 EXPECT_FLOAT_EQ(0, offset.y());
thestigb923f182016-04-05 00:23:33332}
333
Lei Zhangcc9acc12018-03-05 20:49:13334} // namespace chrome_pdf