// Copyright 2019 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/draw_utils/coordinates.h" #include #include #include #include "base/check_op.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h" #include namespace chrome_pdf { namespace draw_utils { IndexedPage::IndexedPage(int index, const gfx::Rect& rect) : index(index), rect(rect) {} IndexedPage::IndexedPage(const IndexedPage& other) = default; IndexedPage& IndexedPage::operator=(const IndexedPage& other) = default; IndexedPage::~IndexedPage() = default; void AdjustBottomGapForRightSidePage(int page_x, gfx::Rect* bottom_gap) { bottom_gap->set_x(page_x); bottom_gap->set_width(bottom_gap->width() / 2); } void CenterRectHorizontally(int doc_width, gfx::Rect* rect) { DCHECK_GE(doc_width, rect->width()); rect->set_x((doc_width - rect->width()) / 2); } void ExpandDocumentSize(const gfx::Size& rect_size, gfx::Size* doc_size) { int width_diff = std::max(0, rect_size.width() - doc_size->width()); doc_size->Enlarge(width_diff, rect_size.height()); } gfx::Rect GetBottomGapBetweenRects(int page_rect_bottom, const gfx::Rect& bottom_rect) { if (page_rect_bottom >= bottom_rect.bottom()) return gfx::Rect(0, 0, 0, 0); return gfx::Rect(bottom_rect.x(), page_rect_bottom, bottom_rect.width(), bottom_rect.bottom() - page_rect_bottom); } int GetMostVisiblePage(const std::vector& visible_pages, const gfx::Rect& visible_screen) { if (visible_pages.empty()) return -1; int most_visible_page_index = visible_pages.front().index; float most_visible_page_area = 0; for (const auto& visible_page : visible_pages) { float page_area = gfx::SizeF(visible_page.rect.size()).GetArea(); // TODO(thestig): Check whether we can remove this check. if (page_area <= 0) continue; gfx::Rect screen_intersect = gfx::IntersectRects(visible_screen, visible_page.rect); float intersect_area = gfx::SizeF(screen_intersect.size()).GetArea() / page_area; if (intersect_area > most_visible_page_area) { most_visible_page_index = visible_page.index; most_visible_page_area = intersect_area; } } return most_visible_page_index; } PageInsetSizes GetPageInsetsForTwoUpView( size_t page_index, size_t num_of_pages, const PageInsetSizes& single_view_insets, int horizontal_separator) { DCHECK_LT(page_index, num_of_pages); // Don't change |two_up_insets| if the page is on the left side and is the // last page. In this case, the shadows on both sides should be the same size. PageInsetSizes two_up_insets = single_view_insets; if (page_index % 2 == 1) two_up_insets.left = horizontal_separator; else if (page_index != num_of_pages - 1) two_up_insets.right = horizontal_separator; return two_up_insets; } gfx::Rect GetRectForSingleView(const gfx::Size& rect_size, const gfx::Size& document_size) { gfx::Rect page_rect({0, document_size.height()}, rect_size); CenterRectHorizontally(document_size.width(), &page_rect); return page_rect; } gfx::Rect GetScreenRect(const gfx::Rect& rect, const gfx::Point& position, double zoom) { DCHECK_GT(zoom, 0); int x = static_cast(rect.x() * zoom - position.x()); int y = static_cast(rect.y() * zoom - position.y()); int right = static_cast(ceil(rect.right() * zoom - position.x())); int bottom = static_cast(ceil(rect.bottom() * zoom - position.y())); return gfx::Rect(x, y, right - x, bottom - y); } gfx::Rect GetSurroundingRect(int page_y, int page_height, const PageInsetSizes& inset_sizes, int doc_width, int bottom_separator) { return gfx::Rect( 0, page_y - inset_sizes.top, doc_width, page_height + inset_sizes.top + inset_sizes.bottom + bottom_separator); } gfx::Rect GetLeftFillRect(const gfx::Rect& page_rect, const PageInsetSizes& inset_sizes, int bottom_separator) { DCHECK_GE(page_rect.x(), inset_sizes.left); return gfx::Rect(0, page_rect.y() - inset_sizes.top, page_rect.x() - inset_sizes.left, page_rect.height() + inset_sizes.top + inset_sizes.bottom + bottom_separator); } gfx::Rect GetRightFillRect(const gfx::Rect& page_rect, const PageInsetSizes& inset_sizes, int doc_width, int bottom_separator) { int right_gap_x = page_rect.right() + inset_sizes.right; DCHECK_GE(doc_width, right_gap_x); return gfx::Rect(right_gap_x, page_rect.y() - inset_sizes.top, doc_width - right_gap_x, page_rect.height() + inset_sizes.top + inset_sizes.bottom + bottom_separator); } gfx::Rect GetBottomFillRect(const gfx::Rect& page_rect, const PageInsetSizes& inset_sizes, int bottom_separator) { return gfx::Rect(page_rect.x() - inset_sizes.left, page_rect.bottom() + inset_sizes.bottom, page_rect.width() + inset_sizes.left + inset_sizes.right, bottom_separator); } gfx::Rect GetLeftRectForTwoUpView(const gfx::Size& rect_size, const gfx::Point& position) { DCHECK_LE(rect_size.width(), position.x()); return gfx::Rect(position.x() - rect_size.width(), position.y(), rect_size.width(), rect_size.height()); } gfx::Rect GetRightRectForTwoUpView(const gfx::Size& rect_size, const gfx::Point& position) { return gfx::Rect(position, rect_size); } } // namespace draw_utils } // namespace chrome_pdf