From 3b20ec77c760ef11dacf00a3e654d06cadf20c27 Mon Sep 17 00:00:00 2001 From: Jane Liu Date: Mon, 21 Aug 2017 11:30:45 -0400 Subject: Avoid annotation popups to be clipped at page edges Currently, annotation popups are placed at a fixed location relative to the annotation. If an annotation is too much on the right or the bottom of the page, then its popup will be clipped at the edge of the page. This CL translates the popups appropriately to avoid getting clipped at page edges. Also, if an annotation is at the bottom-right corner of the page, then the popup is placed above and to the left of the annotation, instead of below and to the right of it. See a set of comparison screenshots here: https://drive.google.com/drive/folders/0B7Fvv7JszRyGZXZXR05yVEFWSlE?usp=sharing Bug=chromium:645367,pdfium:750 Change-Id: Ie048281e965523c292dcc704b51188d794f8877b Reviewed-on: https://pdfium-review.googlesource.com/11470 Commit-Queue: Jane Liu Reviewed-by: dsinclair --- core/fpdfdoc/cpdf_annotlist.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp index 1f94779c15..e4ecf466f5 100644 --- a/core/fpdfdoc/cpdf_annotlist.cpp +++ b/core/fpdfdoc/cpdf_annotlist.cpp @@ -6,6 +6,7 @@ #include "core/fpdfdoc/cpdf_annotlist.h" +#include #include #include @@ -26,7 +27,8 @@ namespace { std::unique_ptr CreatePopupAnnot(CPDF_Annot* pAnnot, - CPDF_Document* pDocument) { + CPDF_Document* pDocument, + CPDF_Page* pPage) { CPDF_Dictionary* pParentDict = pAnnot->GetAnnotDict(); if (!pParentDict) return nullptr; @@ -48,7 +50,20 @@ std::unique_ptr CreatePopupAnnot(CPDF_Annot* pAnnot, CFX_FloatRect rect = pParentDict->GetRectFor("Rect"); rect.Normalize(); CFX_FloatRect popupRect(0, 0, 200, 200); - popupRect.Translate(rect.left, rect.bottom - popupRect.Height()); + // Note that if the popup can set its own dimensions, then we will need to + // make sure that it isn't larger than the page size. + if (rect.left + popupRect.Width() > pPage->GetPageWidth() && + rect.bottom - popupRect.Height() < 0) { + // If the annotation is on the bottom-right corner of the page, then place + // the popup above and to the left of the annotation. + popupRect.Translate(rect.right - popupRect.Width(), rect.top); + } else { + // Place the popup below and to the right of the annotation without getting + // clipped by page edges. + popupRect.Translate( + std::min(rect.left, pPage->GetPageWidth() - popupRect.Width()), + std::max(rect.bottom - popupRect.Height(), 0.f)); + } pAnnotDict->SetRectFor("Rect", popupRect); pAnnotDict->SetNewFor("F", 0); @@ -94,7 +109,7 @@ CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) size_t nAnnotListSize = m_AnnotList.size(); for (size_t i = 0; i < nAnnotListSize; ++i) { std::unique_ptr pPopupAnnot( - CreatePopupAnnot(m_AnnotList[i].get(), m_pDocument)); + CreatePopupAnnot(m_AnnotList[i].get(), m_pDocument, pPage)); if (pPopupAnnot) m_AnnotList.push_back(std::move(pPopupAnnot)); } -- cgit v1.2.3