123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "pdf/pdf_transform.h"
- #include <algorithm>
- #include <utility>
- #include "base/notreached.h"
- #include "ui/gfx/geometry/point_f.h"
- #include "ui/gfx/geometry/rect.h"
- #include "ui/gfx/geometry/size_f.h"
- namespace chrome_pdf {
- namespace {
- // When a PdfRectangle has top < bottom, or right < left, the values should be
- // swapped.
- void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
- if (rect->top < rect->bottom)
- std::swap(rect->top, rect->bottom);
- if (rect->right < rect->left)
- std::swap(rect->right, rect->left);
- }
- } // namespace
- float CalculateScaleFactor(const gfx::Rect& content_rect,
- const gfx::SizeF& src_size,
- bool rotated) {
- if (src_size.IsEmpty())
- return 1.0f;
- float actual_source_page_width =
- rotated ? src_size.height() : src_size.width();
- float actual_source_page_height =
- rotated ? src_size.width() : src_size.height();
- float ratio_x = content_rect.width() / actual_source_page_width;
- float ratio_y = content_rect.height() / actual_source_page_height;
- return std::min(ratio_x, ratio_y);
- }
- void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) {
- constexpr int kDpi = 72;
- constexpr float kPaperWidth = 8.5 * kDpi;
- constexpr float kPaperHeight = 11 * kDpi;
- clip_box->left = 0;
- clip_box->bottom = 0;
- clip_box->right = rotated ? kPaperHeight : kPaperWidth;
- clip_box->top = rotated ? kPaperWidth : kPaperHeight;
- }
- void CalculateMediaBoxAndCropBox(bool rotated,
- bool has_media_box,
- bool has_crop_box,
- PdfRectangle* media_box,
- PdfRectangle* crop_box) {
- if (has_media_box)
- SwapPdfRectangleValuesIfNeeded(media_box);
- if (has_crop_box)
- SwapPdfRectangleValuesIfNeeded(crop_box);
- if (!has_media_box && !has_crop_box) {
- SetDefaultClipBox(rotated, crop_box);
- SetDefaultClipBox(rotated, media_box);
- } else if (has_crop_box && !has_media_box) {
- *media_box = *crop_box;
- } else if (has_media_box && !has_crop_box) {
- *crop_box = *media_box;
- }
- }
- PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
- const PdfRectangle& crop_box) {
- PdfRectangle clip_box;
- // Clip `media_box` to the size of `crop_box`, but ignore `crop_box` if it is
- // bigger than `media_box`.
- clip_box.left = std::max(crop_box.left, media_box.left);
- clip_box.bottom = std::max(crop_box.bottom, media_box.bottom);
- clip_box.right = std::min(crop_box.right, media_box.right);
- clip_box.top = std::min(crop_box.top, media_box.top);
- return clip_box;
- }
- void ScalePdfRectangle(float scale_factor, PdfRectangle* rect) {
- rect->left *= scale_factor;
- rect->bottom *= scale_factor;
- rect->right *= scale_factor;
- rect->top *= scale_factor;
- }
- gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
- const PdfRectangle& source_clip_box) {
- const float clip_box_width = source_clip_box.right - source_clip_box.left;
- const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
- // Center the intended clip region to real clip region.
- return gfx::PointF((content_rect.width() - clip_box_width) / 2 +
- content_rect.x() - source_clip_box.left,
- (content_rect.height() - clip_box_height) / 2 +
- content_rect.y() - source_clip_box.bottom);
- }
- gfx::PointF CalculateNonScaledClipBoxOffset(
- int rotation,
- int page_width,
- int page_height,
- const PdfRectangle& source_clip_box) {
- // Align the intended clip region to left-top corner of real clip region.
- switch (rotation) {
- case 0:
- return gfx::PointF(-1 * source_clip_box.left,
- page_height - source_clip_box.top);
- case 1:
- return gfx::PointF(0, -1 * source_clip_box.bottom);
- case 2:
- return gfx::PointF(page_width - source_clip_box.right, 0);
- case 3:
- return gfx::PointF(page_height - source_clip_box.right,
- page_width - source_clip_box.top);
- default:
- NOTREACHED();
- return gfx::PointF();
- }
- }
- } // namespace chrome_pdf
|