pdf_transform_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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. #include "pdf/pdf_transform.h"
  5. #include "printing/units.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. #include "ui/gfx/geometry/point_f.h"
  8. #include "ui/gfx/geometry/rect.h"
  9. #include "ui/gfx/geometry/size_f.h"
  10. namespace chrome_pdf {
  11. namespace {
  12. constexpr float kDefaultWidth = 8.5 * printing::kPointsPerInch;
  13. constexpr float kDefaultHeight = 11.0 * printing::kPointsPerInch;
  14. constexpr float kDefaultRatio = kDefaultWidth / kDefaultHeight;
  15. constexpr float kTolerance = 0.0001f;
  16. void ExpectDefaultPortraitBox(const PdfRectangle& box) {
  17. EXPECT_FLOAT_EQ(0, box.left);
  18. EXPECT_FLOAT_EQ(0, box.bottom);
  19. EXPECT_FLOAT_EQ(kDefaultWidth, box.right);
  20. EXPECT_FLOAT_EQ(kDefaultHeight, box.top);
  21. }
  22. void ExpectDefaultLandscapeBox(const PdfRectangle& box) {
  23. EXPECT_FLOAT_EQ(0, box.left);
  24. EXPECT_FLOAT_EQ(0, box.bottom);
  25. EXPECT_FLOAT_EQ(kDefaultHeight, box.right);
  26. EXPECT_FLOAT_EQ(kDefaultWidth, box.top);
  27. }
  28. void ExpectBoxesAreEqual(const PdfRectangle& expected,
  29. const PdfRectangle& actual) {
  30. EXPECT_FLOAT_EQ(expected.left, actual.left);
  31. EXPECT_FLOAT_EQ(expected.bottom, actual.bottom);
  32. EXPECT_FLOAT_EQ(expected.right, actual.right);
  33. EXPECT_FLOAT_EQ(expected.top, actual.top);
  34. }
  35. void InitializeBoxToInvalidValues(PdfRectangle* box) {
  36. box->left = box->bottom = box->right = box->top = -1;
  37. }
  38. void InitializeBoxToDefaultPortraitValues(PdfRectangle* box) {
  39. box->left = 0;
  40. box->bottom = 0;
  41. box->right = kDefaultWidth;
  42. box->top = kDefaultHeight;
  43. }
  44. void InitializeBoxToDefaultLandscapeValue(PdfRectangle* box) {
  45. box->left = 0;
  46. box->bottom = 0;
  47. box->right = kDefaultHeight;
  48. box->top = kDefaultWidth;
  49. }
  50. } // namespace
  51. TEST(PdfTransformTest, CalculateScaleFactor) {
  52. static constexpr gfx::SizeF kSize(kDefaultWidth, kDefaultHeight);
  53. gfx::Rect rect(kDefaultWidth, kDefaultHeight);
  54. float scale;
  55. // 1:1
  56. scale = CalculateScaleFactor(rect, kSize, false);
  57. EXPECT_NEAR(1.0f, scale, kTolerance);
  58. scale = CalculateScaleFactor(rect, kSize, true);
  59. EXPECT_NEAR(kDefaultRatio, scale, kTolerance);
  60. // 1:2
  61. rect = gfx::Rect(kDefaultWidth / 2, kDefaultHeight / 2);
  62. scale = CalculateScaleFactor(rect, kSize, false);
  63. EXPECT_NEAR(0.5f, scale, kTolerance);
  64. scale = CalculateScaleFactor(rect, kSize, true);
  65. EXPECT_NEAR(kDefaultRatio / 2, scale, kTolerance);
  66. // 3:1
  67. rect = gfx::Rect(kDefaultWidth * 3, kDefaultHeight * 3);
  68. scale = CalculateScaleFactor(rect, kSize, false);
  69. EXPECT_NEAR(3.0f, scale, kTolerance);
  70. scale = CalculateScaleFactor(rect, kSize, true);
  71. EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
  72. // 3:1, rotated.
  73. rect = gfx::Rect(kDefaultHeight * 3, kDefaultWidth * 3);
  74. scale = CalculateScaleFactor(rect, kSize, false);
  75. EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
  76. scale = CalculateScaleFactor(rect, kSize, true);
  77. EXPECT_NEAR(3.0f, scale, kTolerance);
  78. // Odd size
  79. rect = gfx::Rect(10, 1000);
  80. scale = CalculateScaleFactor(rect, kSize, false);
  81. EXPECT_NEAR(0.01634f, scale, kTolerance);
  82. scale = CalculateScaleFactor(rect, kSize, true);
  83. EXPECT_NEAR(0.01263f, scale, kTolerance);
  84. }
  85. TEST(PdfTransformTest, SetDefaultClipBox) {
  86. PdfRectangle box;
  87. SetDefaultClipBox(false, &box);
  88. ExpectDefaultPortraitBox(box);
  89. SetDefaultClipBox(true, &box);
  90. ExpectDefaultLandscapeBox(box);
  91. }
  92. TEST(PdfTransformTest, CalculateMediaBoxAndCropBox) {
  93. PdfRectangle media_box;
  94. PdfRectangle crop_box;
  95. // Assume both boxes are there.
  96. InitializeBoxToDefaultPortraitValues(&media_box);
  97. InitializeBoxToDefaultLandscapeValue(&crop_box);
  98. CalculateMediaBoxAndCropBox(true, true, true, &media_box, &crop_box);
  99. ExpectDefaultPortraitBox(media_box);
  100. ExpectDefaultLandscapeBox(crop_box);
  101. // Assume both boxes are missing.
  102. InitializeBoxToInvalidValues(&media_box);
  103. InitializeBoxToInvalidValues(&crop_box);
  104. CalculateMediaBoxAndCropBox(false, false, false, &media_box, &crop_box);
  105. ExpectDefaultPortraitBox(media_box);
  106. ExpectDefaultPortraitBox(crop_box);
  107. CalculateMediaBoxAndCropBox(true, false, false, &media_box, &crop_box);
  108. ExpectDefaultLandscapeBox(media_box);
  109. ExpectDefaultLandscapeBox(crop_box);
  110. // Assume crop box is missing.
  111. constexpr PdfRectangle expected_box = {0, 0, 42, 420};
  112. media_box = expected_box;
  113. InitializeBoxToInvalidValues(&crop_box);
  114. CalculateMediaBoxAndCropBox(false, true, false, &media_box, &crop_box);
  115. ExpectBoxesAreEqual(expected_box, media_box);
  116. ExpectBoxesAreEqual(expected_box, crop_box);
  117. // Assume media box is missing.
  118. InitializeBoxToInvalidValues(&media_box);
  119. CalculateMediaBoxAndCropBox(false, false, true, &media_box, &crop_box);
  120. ExpectBoxesAreEqual(expected_box, media_box);
  121. ExpectBoxesAreEqual(expected_box, crop_box);
  122. }
  123. TEST(PdfTransformTest, CalculateClipBoxBoundary) {
  124. PdfRectangle media_box;
  125. PdfRectangle crop_box;
  126. PdfRectangle result;
  127. // media box and crop box are the same.
  128. InitializeBoxToDefaultPortraitValues(&media_box);
  129. InitializeBoxToDefaultPortraitValues(&crop_box);
  130. result = CalculateClipBoxBoundary(media_box, crop_box);
  131. ExpectDefaultPortraitBox(result);
  132. // media box is portrait and crop box is landscape.
  133. InitializeBoxToDefaultLandscapeValue(&crop_box);
  134. result = CalculateClipBoxBoundary(media_box, crop_box);
  135. EXPECT_FLOAT_EQ(0, result.left);
  136. EXPECT_FLOAT_EQ(0, result.bottom);
  137. EXPECT_FLOAT_EQ(kDefaultWidth, result.right);
  138. EXPECT_FLOAT_EQ(kDefaultWidth, result.top);
  139. // crop box is smaller than media box.
  140. crop_box.left = 0;
  141. crop_box.bottom = 0;
  142. crop_box.right = 100;
  143. crop_box.top = 200;
  144. result = CalculateClipBoxBoundary(media_box, crop_box);
  145. EXPECT_FLOAT_EQ(0, result.left);
  146. EXPECT_FLOAT_EQ(0, result.bottom);
  147. EXPECT_FLOAT_EQ(100, result.right);
  148. EXPECT_FLOAT_EQ(200, result.top);
  149. // crop box is smaller than the media box in one dimension and longer in the
  150. // other.
  151. crop_box.left = 0;
  152. crop_box.bottom = 0;
  153. crop_box.right = 100;
  154. crop_box.top = 2000;
  155. result = CalculateClipBoxBoundary(media_box, crop_box);
  156. EXPECT_FLOAT_EQ(0, result.left);
  157. EXPECT_FLOAT_EQ(0, result.bottom);
  158. EXPECT_FLOAT_EQ(100, result.right);
  159. EXPECT_FLOAT_EQ(kDefaultHeight, result.top);
  160. }
  161. TEST(PdfTransformTest, CalculateScaledClipBoxOffset) {
  162. constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
  163. PdfRectangle clip_box;
  164. gfx::PointF offset;
  165. // `rect` and `clip_box` are the same size.
  166. InitializeBoxToDefaultPortraitValues(&clip_box);
  167. offset = CalculateScaledClipBoxOffset(rect, clip_box);
  168. EXPECT_FLOAT_EQ(0, offset.x());
  169. EXPECT_FLOAT_EQ(0, offset.y());
  170. // `rect` is larger than `clip_box`.
  171. clip_box.top /= 2;
  172. clip_box.right /= 4;
  173. offset = CalculateScaledClipBoxOffset(rect, clip_box);
  174. EXPECT_FLOAT_EQ(229.5f, offset.x());
  175. EXPECT_FLOAT_EQ(198, offset.y());
  176. }
  177. TEST(PdfTransformTest, CalculateNonScaledClipBoxOffset) {
  178. int page_width = kDefaultWidth;
  179. int page_height = kDefaultHeight;
  180. PdfRectangle clip_box;
  181. gfx::PointF offset;
  182. // `rect`, page size and `clip_box` are the same.
  183. InitializeBoxToDefaultPortraitValues(&clip_box);
  184. offset =
  185. CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
  186. EXPECT_FLOAT_EQ(0, offset.x());
  187. EXPECT_FLOAT_EQ(0, offset.y());
  188. offset =
  189. CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
  190. EXPECT_FLOAT_EQ(0, offset.x());
  191. EXPECT_FLOAT_EQ(0, offset.y());
  192. offset =
  193. CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
  194. EXPECT_FLOAT_EQ(0, offset.x());
  195. EXPECT_FLOAT_EQ(0, offset.y());
  196. offset =
  197. CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
  198. EXPECT_FLOAT_EQ(180, offset.x());
  199. EXPECT_FLOAT_EQ(-180, offset.y());
  200. // Smaller `clip_box`.
  201. clip_box.top /= 4;
  202. clip_box.right /= 2;
  203. offset =
  204. CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
  205. EXPECT_FLOAT_EQ(0, offset.x());
  206. EXPECT_FLOAT_EQ(594, offset.y());
  207. offset =
  208. CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
  209. EXPECT_FLOAT_EQ(0, offset.x());
  210. EXPECT_FLOAT_EQ(0, offset.y());
  211. offset =
  212. CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
  213. EXPECT_FLOAT_EQ(306, offset.x());
  214. EXPECT_FLOAT_EQ(0, offset.y());
  215. offset =
  216. CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
  217. EXPECT_FLOAT_EQ(486, offset.x());
  218. EXPECT_FLOAT_EQ(414, offset.y());
  219. // Larger page size.
  220. InitializeBoxToDefaultPortraitValues(&clip_box);
  221. page_width += 10;
  222. page_height += 20;
  223. offset =
  224. CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
  225. EXPECT_FLOAT_EQ(0, offset.x());
  226. EXPECT_FLOAT_EQ(20, offset.y());
  227. offset =
  228. CalculateNonScaledClipBoxOffset(1, page_width, page_height, clip_box);
  229. EXPECT_FLOAT_EQ(0, offset.x());
  230. EXPECT_FLOAT_EQ(0, offset.y());
  231. offset =
  232. CalculateNonScaledClipBoxOffset(2, page_width, page_height, clip_box);
  233. EXPECT_FLOAT_EQ(10, offset.x());
  234. EXPECT_FLOAT_EQ(0, offset.y());
  235. offset =
  236. CalculateNonScaledClipBoxOffset(3, page_width, page_height, clip_box);
  237. EXPECT_FLOAT_EQ(200, offset.x());
  238. EXPECT_FLOAT_EQ(-170, offset.y());
  239. }
  240. // https://crbug.com/491160 and https://crbug.com/588757
  241. TEST(PdfTransformTest, ReversedMediaBox) {
  242. int page_width = kDefaultWidth;
  243. int page_height = kDefaultHeight;
  244. constexpr gfx::Rect rect(kDefaultWidth, kDefaultHeight);
  245. PdfRectangle clip_box;
  246. gfx::PointF offset;
  247. constexpr PdfRectangle expected_media_box_b491160 = {0, -792, 612, 0};
  248. PdfRectangle media_box_b491160 = {0, 0, 612, -792};
  249. CalculateMediaBoxAndCropBox(false, true, false, &media_box_b491160,
  250. &clip_box);
  251. ExpectBoxesAreEqual(expected_media_box_b491160, media_box_b491160);
  252. ExpectBoxesAreEqual(expected_media_box_b491160, clip_box);
  253. offset = CalculateScaledClipBoxOffset(rect, media_box_b491160);
  254. EXPECT_FLOAT_EQ(0, offset.x());
  255. EXPECT_FLOAT_EQ(792, offset.y());
  256. offset = CalculateNonScaledClipBoxOffset(0, page_width, page_height,
  257. media_box_b491160);
  258. EXPECT_FLOAT_EQ(0, offset.x());
  259. EXPECT_FLOAT_EQ(792, offset.y());
  260. PdfRectangle media_box_b588757 = {0, 792, 612, 0};
  261. CalculateMediaBoxAndCropBox(false, true, false, &media_box_b588757,
  262. &clip_box);
  263. ExpectDefaultPortraitBox(media_box_b588757);
  264. ExpectDefaultPortraitBox(clip_box);
  265. offset = CalculateScaledClipBoxOffset(rect, clip_box);
  266. EXPECT_FLOAT_EQ(0, offset.x());
  267. EXPECT_FLOAT_EQ(0, offset.y());
  268. offset =
  269. CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
  270. EXPECT_FLOAT_EQ(0, offset.x());
  271. EXPECT_FLOAT_EQ(0, offset.y());
  272. PdfRectangle media_box_left_right_flipped = {612, 792, 0, 0};
  273. CalculateMediaBoxAndCropBox(false, true, false, &media_box_left_right_flipped,
  274. &clip_box);
  275. ExpectDefaultPortraitBox(media_box_left_right_flipped);
  276. ExpectDefaultPortraitBox(clip_box);
  277. offset = CalculateScaledClipBoxOffset(rect, clip_box);
  278. EXPECT_FLOAT_EQ(0, offset.x());
  279. EXPECT_FLOAT_EQ(0, offset.y());
  280. offset =
  281. CalculateNonScaledClipBoxOffset(0, page_width, page_height, clip_box);
  282. EXPECT_FLOAT_EQ(0, offset.x());
  283. EXPECT_FLOAT_EQ(0, offset.y());
  284. }
  285. } // namespace chrome_pdf