diff options
author | Henrique Nakashima <hnakashima@chromium.org> | 2018-03-21 20:00:47 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-03-21 20:00:47 +0000 |
commit | 19a33e4ece99c4bb438d870c52fbc5ed5e80c897 (patch) | |
tree | 5e68516a2930b50b0825d769a9c5dcd6da5d337a /fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp | |
parent | 11767d3ba1b453f666a084b9850a5f020c28993f (diff) | |
download | pdfium-19a33e4ece99c4bb438d870c52fbc5ed5e80c897.tar.xz |
Rewrite CPDFXFA_DocEnvironment::GetPopupPos.chromium/3378
This is a step to fix XFA combobox popups being rendered outside the
page.
The rest of the fix is in:
https://chromium-review.googlesource.com/c/chromium/src/+/961249
Bug: chromium:820106
Change-Id: I51e5667bc08cdb2028c0afafa6e29e929e661c94
Reviewed-on: https://pdfium-review.googlesource.com/28371
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp')
-rw-r--r-- | fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp | 135 |
1 files changed, 76 insertions, 59 deletions
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp index cb6ce1ccf8..c9087e8a0b 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp +++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp @@ -123,98 +123,115 @@ bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget, if (!pFormFillEnv) return false; - FS_RECTF pageViewRect = {0.0f, 0.0f, 0.0f, 0.0f}; - pFormFillEnv->GetPageViewRect(pPage.Get(), pageViewRect); + FS_RECTF page_view_rect = {0.0f, 0.0f, 0.0f, 0.0f}; + pFormFillEnv->GetPageViewRect(pPage.Get(), page_view_rect); - int t1; - int t2; - CFX_FloatRect rcAnchor = rtAnchor.ToFloatRect(); int nRotate = hWidget->GetNode()->GetRotate(); + + int space_available_below_anchor; + int space_available_above_anchor; switch (nRotate) { + case 0: + default: { + space_available_below_anchor = + static_cast<int>(page_view_rect.bottom - rtAnchor.bottom()); + space_available_above_anchor = + static_cast<int>(rtAnchor.top - page_view_rect.top); + + if (rtAnchor.left < page_view_rect.left) + rtPopup.left += page_view_rect.left - rtAnchor.left; + if (rtAnchor.right() > page_view_rect.right) + rtPopup.left -= rtAnchor.right() - page_view_rect.right; + break; + } case 90: { - t1 = (int)(pageViewRect.right - rcAnchor.right); - t2 = (int)(rcAnchor.left - pageViewRect.left); - if (rcAnchor.bottom < pageViewRect.bottom) - rtPopup.left += rcAnchor.bottom - pageViewRect.bottom; + space_available_below_anchor = + static_cast<int>(page_view_rect.right - rtAnchor.right()); + space_available_above_anchor = + static_cast<int>(rtAnchor.left - page_view_rect.left); + + if (rtAnchor.bottom() > page_view_rect.bottom) + rtPopup.left += rtAnchor.bottom() - page_view_rect.bottom; + if (rtAnchor.top < page_view_rect.top) + rtPopup.left -= page_view_rect.top - rtAnchor.top; break; } case 180: { - t2 = (int)(pageViewRect.top - rcAnchor.top); - t1 = (int)(rcAnchor.bottom - pageViewRect.bottom); - if (rcAnchor.left < pageViewRect.left) - rtPopup.left += rcAnchor.left - pageViewRect.left; + space_available_below_anchor = + static_cast<int>(rtAnchor.top - page_view_rect.top); + space_available_above_anchor = + static_cast<int>(page_view_rect.bottom - rtAnchor.bottom()); + + if (rtAnchor.right() > page_view_rect.right) + rtPopup.left += rtAnchor.right() - page_view_rect.right; + if (rtAnchor.left < page_view_rect.left) + rtPopup.left -= page_view_rect.left - rtAnchor.left; break; } case 270: { - t1 = (int)(rcAnchor.left - pageViewRect.left); - t2 = (int)(pageViewRect.right - rcAnchor.right); - if (rcAnchor.top > pageViewRect.top) - rtPopup.left -= rcAnchor.top - pageViewRect.top; - break; - } - case 0: - default: { - t1 = (int)(pageViewRect.top - rcAnchor.top); - t2 = (int)(rcAnchor.bottom - pageViewRect.bottom); - if (rcAnchor.right > pageViewRect.right) - rtPopup.left -= rcAnchor.right - pageViewRect.right; + space_available_below_anchor = + static_cast<int>(rtAnchor.left - page_view_rect.left); + space_available_above_anchor = + static_cast<int>(page_view_rect.right - rtAnchor.right()); + + if (rtAnchor.top < page_view_rect.top) + rtPopup.left += page_view_rect.top - rtAnchor.top; + if (rtAnchor.bottom() > page_view_rect.bottom) + rtPopup.left -= rtAnchor.bottom() - page_view_rect.bottom; break; } } - int t; - uint32_t dwPos; - if (t1 <= 0 && t2 <= 0) + // If there is no space on either side, the popup can't be rendered. + if (space_available_below_anchor <= 0 && space_available_above_anchor <= 0) return false; - if (t1 <= 0) { - t = t2; - dwPos = 1; - } else if (t2 <= 0) { - t = t1; - dwPos = 0; - } else if (t1 > t2) { - t = t1; - dwPos = 0; - } else { - t = t2; - dwPos = 1; - } - float fPopupHeight; - if (t < fMinPopup) - fPopupHeight = fMinPopup; - else if (t > fMaxPopup) - fPopupHeight = fMaxPopup; + // Determine whether to draw above or below the anchor. + bool draw_below_anchor; + if (space_available_below_anchor <= 0) + draw_below_anchor = false; + else if (space_available_above_anchor <= 0) + draw_below_anchor = true; + else if (space_available_below_anchor > space_available_above_anchor) + draw_below_anchor = true; + else + draw_below_anchor = false; + + int space_available = (draw_below_anchor ? space_available_below_anchor + : space_available_above_anchor); + + // Set the popup height and y position according to what was decided above. + float popup_height; + if (space_available < fMinPopup) + popup_height = fMinPopup; + else if (space_available > fMaxPopup) + popup_height = fMaxPopup; else - fPopupHeight = static_cast<float>(t); + popup_height = static_cast<float>(space_available); switch (nRotate) { case 0: case 180: { - if (dwPos == 0) { + if (draw_below_anchor) rtPopup.top = rtAnchor.height; - rtPopup.height = fPopupHeight; - } else { - rtPopup.top = -fPopupHeight; - rtPopup.height = fPopupHeight; - } + else + rtPopup.top = -popup_height; break; } case 90: case 270: { - if (dwPos == 0) { + if (draw_below_anchor) rtPopup.top = rtAnchor.width; - rtPopup.height = fPopupHeight; - } else { - rtPopup.top = -fPopupHeight; - rtPopup.height = fPopupHeight; - } + else + rtPopup.top = -popup_height; break; } default: break; } + rtPopup.height = popup_height; + return true; } |