Fix caret not appearing in XFA Edits.

This makes the caret appear (again?), blink, and fixes its positioning
to be a little spaced from the last character.

Known issue: when the edit is empty, the caret is not necessarily
aligned with where the text will be.

Bug: chromium:592750
Change-Id: I950b0ea236db8855c6ed50f48ec1935d97e6ccf8
Reviewed-on: https://pdfium-review.googlesource.com/25451
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/DEPS b/DEPS
index 8c70d4c..260a988 100644
--- a/DEPS
+++ b/DEPS
@@ -29,7 +29,7 @@
   'jinja2_revision': 'd34383206fa42d52faa10bb9931d6d538f3a57e0',
   'jpeg_turbo_revision': '7260e4d8b8e1e40b17f03fafdf1cd83296900f76',
   'markupsafe_revision': '8f45f5cfa0009d2a70589bcda0349b8cb2b72783',
-  'pdfium_tests_revision': '5e71e2580fb8d720f21f48c8ba8070b195fbff2c',
+  'pdfium_tests_revision': 'adcc738d124799800ab2f3eb7cf0dfbd301cd759',
   'skia_revision': '40ca2087ef0752d78fd2e0995471102fe96fe9fe',
   'tools_memory_revision': '427f10475e1a8d72424c29d00bf689122b738e5d',
   'trace_event_revision': '0e9a47d74970bee1bbfc063c47215406f8918699',
diff --git a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
index d763f02..96ccc1c 100644
--- a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
+++ b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
@@ -18,7 +18,7 @@
 class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr {
  public:
   explicit CXFA_FWLAdapterTimerMgr(CPDFSDK_FormFillEnvironment* pFormFillEnv);
-  ~CXFA_FWLAdapterTimerMgr();
+  ~CXFA_FWLAdapterTimerMgr() override;
 
   void Start(CFWL_Timer* pTimer,
              uint32_t dwElapse,
diff --git a/xfa/fde/cfde_texteditengine.cpp b/xfa/fde/cfde_texteditengine.cpp
index d085a8d..75fd103 100644
--- a/xfa/fde/cfde_texteditengine.cpp
+++ b/xfa/fde/cfde_texteditengine.cpp
@@ -1071,10 +1071,8 @@
     if (it->nStart <= start_idx && start_idx < it->nStart + it->nCount)
       break;
   }
-  if (it == text_piece_info_.end()) {
-    NOTREACHED();
+  if (it == text_piece_info_.end())
     return {0, CFX_RectF()};
-  }
 
   return {it->nBidiLevel, GetCharRects(*it)[start_idx - it->nStart]};
 }
diff --git a/xfa/fwl/cfwl_caret.cpp b/xfa/fwl/cfwl_caret.cpp
index cd85041..03c8ffd 100644
--- a/xfa/fwl/cfwl_caret.cpp
+++ b/xfa/fwl/cfwl_caret.cpp
@@ -58,17 +58,21 @@
 }
 
 void CFWL_Caret::ShowCaret() {
-  if (m_pTimerInfo)
-    m_pTimerInfo->StopTimer();
+  if (m_pTimerInfo) {
+    CFWL_TimerInfo* pOldTimerInfo = m_pTimerInfo.Release();
+    pOldTimerInfo->StopTimer();
+  }
+
   m_pTimerInfo = m_pTimer->StartTimer(kFrequency, true);
   RemoveStates(FWL_WGTSTATE_Invisible);
 }
 
 void CFWL_Caret::HideCaret() {
   if (m_pTimerInfo) {
-    m_pTimerInfo->StopTimer();
-    m_pTimerInfo = nullptr;
+    CFWL_TimerInfo* pOldTimerInfo = m_pTimerInfo.Release();
+    pOldTimerInfo->StopTimer();
   }
+
   SetStates(FWL_WGTSTATE_Invisible);
 }
 
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index 960ec99..051c39f 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -79,7 +79,6 @@
   m_rtEngine.Reset();
   m_rtStatic.Reset();
 
-  InitCaret();
   m_EdtEngine.SetDelegate(this);
 }
 
@@ -1065,8 +1064,14 @@
 }
 
 void CFWL_Edit::InitCaret() {
-  m_pCaret.reset();
-  m_rtCaret = CFX_RectF();
+  if (m_pCaret)
+    return;
+
+  m_pCaret = pdfium::MakeUnique<CFWL_Caret>(
+      m_pOwnerApp.Get(), pdfium::MakeUnique<CFWL_WidgetProperties>(), this);
+  m_pCaret->SetParent(this);
+  m_pCaret->SetStates(m_pProperties->m_dwStates);
+  UpdateCursorRect();
 }
 
 void CFWL_Edit::UpdateCursorRect() {
@@ -1076,10 +1081,12 @@
       m_EdtEngine.GetCharacterInfo(m_CursorPosition);
   // TODO(dsinclair): This should handle bidi level  ...
 
-  if (m_rtCaret.width == 0 && m_rtCaret.left > 1.0f)
-    m_rtCaret.left -= 1.0f;
-
   m_rtCaret.width = 1.0f;
+
+  // TODO(hnakashima): Handle correctly edits with empty text instead of using
+  // these defaults.
+  if (m_rtCaret.height == 0)
+    m_rtCaret.height = 8.0f;
 }
 
 void CFWL_Edit::SetCursorPosition(size_t position) {
diff --git a/xfa/fwl/cfwl_timer.cpp b/xfa/fwl/cfwl_timer.cpp
index 2734e49..597f928 100644
--- a/xfa/fwl/cfwl_timer.cpp
+++ b/xfa/fwl/cfwl_timer.cpp
@@ -25,11 +25,13 @@
   if (!pAdapterNative)
     return nullptr;
 
-  IFWL_AdapterTimerMgr* pAdapterTimerMgr = pAdapterNative->GetTimerMgr();
-  if (!pAdapterTimerMgr)
+  if (!m_pTimeMgrAdapter)
+    m_pTimeMgrAdapter.reset(pAdapterNative->GetTimerMgr());
+
+  if (!m_pTimeMgrAdapter)
     return nullptr;
 
   CFWL_TimerInfo* pTimerInfo = nullptr;
-  pAdapterTimerMgr->Start(this, dwElapse, bImmediately, &pTimerInfo);
+  m_pTimeMgrAdapter->Start(this, dwElapse, bImmediately, &pTimerInfo);
   return pTimerInfo;
 }
diff --git a/xfa/fwl/cfwl_timer.h b/xfa/fwl/cfwl_timer.h
index da1b443..355ea69 100644
--- a/xfa/fwl/cfwl_timer.h
+++ b/xfa/fwl/cfwl_timer.h
@@ -7,11 +7,14 @@
 #ifndef XFA_FWL_CFWL_TIMER_H_
 #define XFA_FWL_CFWL_TIMER_H_
 
+#include <memory>
+
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/unowned_ptr.h"
 
 class CFWL_TimerInfo;
 class CFWL_Widget;
+class IFWL_AdapterTimerMgr;
 
 class CFWL_Timer {
  public:
@@ -23,6 +26,7 @@
 
  protected:
   UnownedPtr<CFWL_Widget> m_pWidget;
+  std::unique_ptr<IFWL_AdapterTimerMgr> m_pTimeMgrAdapter;
 };
 
 #endif  // XFA_FWL_CFWL_TIMER_H_
diff --git a/xfa/fwl/ifwl_adaptertimermgr.h b/xfa/fwl/ifwl_adaptertimermgr.h
index 1f65589..23627d9 100644
--- a/xfa/fwl/ifwl_adaptertimermgr.h
+++ b/xfa/fwl/ifwl_adaptertimermgr.h
@@ -11,6 +11,7 @@
 
 class IFWL_AdapterTimerMgr {
  public:
+  virtual ~IFWL_AdapterTimerMgr() {}
   virtual void Start(CFWL_Timer* pTimer,
                      uint32_t dwElapse,
                      bool bImmediately,