blob: 9e6c3526fe8f22a18dce752db365359347fb9245 [file] [log] [blame]
// 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 <math.h>
#include <algorithm>
#include "base/logging.h"
#include "ppapi/cpp/point.h"
namespace chrome_pdf {
namespace draw_utils {
void AdjustBottomGapForRightSidePage(int page_x, pp::Rect* bottom_gap) {
bottom_gap->set_x(page_x);
bottom_gap->set_width(bottom_gap->width() / 2);
}
void CenterRectHorizontally(int doc_width, pp::Rect* rect) {
DCHECK_GE(doc_width, rect->width());
rect->set_x((doc_width - rect->width()) / 2);
}
void ExpandDocumentSize(const pp::Size& rect_size, pp::Size* doc_size) {
int width_diff = std::max(0, rect_size.width() - doc_size->width());
doc_size->Enlarge(width_diff, rect_size.height());
}
pp::Rect GetBottomGapBetweenRects(int page_rect_bottom,
const pp::Rect& bottom_rect) {
if (page_rect_bottom >= bottom_rect.bottom())
return pp::Rect(0, 0, 0, 0);
return pp::Rect(bottom_rect.x(), page_rect_bottom, bottom_rect.width(),
bottom_rect.bottom() - page_rect_bottom);
}
int GetMostVisiblePage(const std::vector<IndexedPage>& visible_pages,
const pp::Rect& visible_screen) {
if (visible_pages.empty())
return -1;
int most_visible_page_index = visible_pages.front().index;
double most_visible_page_area = 0.0;
for (const auto& visible_page : visible_pages) {
double page_area = static_cast<double>(visible_page.rect.size().GetArea());
// TODO(thestig): Check whether we can remove this check.
if (page_area <= 0.0)
continue;
pp::Rect screen_intersect = visible_screen.Intersect(visible_page.rect);
double intersect_area =
static_cast<double>(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;
}
pp::Rect GetRectForSingleView(const pp::Size& rect_size,
const pp::Size& document_size) {
pp::Rect page_rect({0, document_size.height()}, rect_size);
CenterRectHorizontally(document_size.width(), &page_rect);
return page_rect;
}
pp::Rect GetScreenRect(const pp::Rect& rect,
const pp::Point& position,
double zoom) {
DCHECK_GT(zoom, 0);
int x = static_cast<int>(rect.x() * zoom - position.x());
int y = static_cast<int>(rect.y() * zoom - position.y());
int right = static_cast<int>(ceil(rect.right() * zoom - position.x()));
int bottom = static_cast<int>(ceil(rect.bottom() * zoom - position.y()));
return pp::Rect(x, y, right - x, bottom - y);
}
pp::Rect GetSurroundingRect(int page_y,
int page_height,
const PageInsetSizes& inset_sizes,
int doc_width,
int bottom_separator) {
return pp::Rect(
0, page_y - inset_sizes.top, doc_width,
page_height + inset_sizes.top + inset_sizes.bottom + bottom_separator);
}
pp::Rect GetLeftFillRect(const pp::Rect& page_rect,
const PageInsetSizes& inset_sizes,
int bottom_separator) {
DCHECK_GE(page_rect.x(), inset_sizes.left);
return pp::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);
}
pp::Rect GetRightFillRect(const pp::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 pp::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);
}
pp::Rect GetBottomFillRect(const pp::Rect& page_rect,
const PageInsetSizes& inset_sizes,
int bottom_separator) {
return pp::Rect(page_rect.x() - inset_sizes.left,
page_rect.bottom() + inset_sizes.bottom,
page_rect.width() + inset_sizes.left + inset_sizes.right,
bottom_separator);
}
pp::Rect GetLeftRectForTwoUpView(const pp::Size& rect_size,
const pp::Point& position) {
DCHECK_LE(rect_size.width(), position.x());
return pp::Rect(position.x() - rect_size.width(), position.y(),
rect_size.width(), rect_size.height());
}
pp::Rect GetRightRectForTwoUpView(const pp::Size& rect_size,
const pp::Point& position) {
return pp::Rect(position.x(), position.y(), rect_size.width(),
rect_size.height());
}
} // namespace draw_utils
} // namespace chrome_pdf