bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget,
                                         FX_FLOAT fMinPopup,
                                         FX_FLOAT fMaxPopup,
                                         const CFX_RectF& rtAnchor,
                                         CFX_RectF& rtPopup) {
  if (!hWidget)
    return false;

  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
  if (!pXFAPageView)
    return false;

  CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pXFAPageView);
  if (!pPage)
    return false;

  CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
  int nRotate = pWidgetAcc->GetRotate();
  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  FS_RECTF pageViewRect = {0.0f, 0.0f, 0.0f, 0.0f};
  pFormFillEnv->GetPageViewRect(pPage, pageViewRect);

  int t1;
  int t2;
  CFX_FloatRect rcAnchor = CFX_FloatRect::FromCFXRectF(rtAnchor);
  switch (nRotate) {
    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;
      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;
      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;
      break;
    }
  }

  int t;
  uint32_t dwPos;
  if (t1 <= 0 && t2 <= 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;
  }

  FX_FLOAT fPopupHeight;
  if (t < fMinPopup)
    fPopupHeight = fMinPopup;
  else if (t > fMaxPopup)
    fPopupHeight = fMaxPopup;
  else
    fPopupHeight = static_cast<FX_FLOAT>(t);

  switch (nRotate) {
    case 0:
    case 180: {
      if (dwPos == 0) {
        rtPopup.top = rtAnchor.height;
        rtPopup.height = fPopupHeight;
      } else {
        rtPopup.top = -fPopupHeight;
        rtPopup.height = fPopupHeight;
      }
      break;
    }
    case 90:
    case 270: {
      if (dwPos == 0) {
        rtPopup.top = rtAnchor.width;
        rtPopup.height = fPopupHeight;
      } else {
        rtPopup.top = -fPopupHeight;
        rtPopup.height = fPopupHeight;
      }
      break;
    }
    default:
      break;
  }

  return true;
}