Replace CPVT_ArrayTemplate in cpdf_variabletext.cpp and remove it.

Change-Id: I4354a841d6e2d4f30ccb298d13dffa49b9f3a3b3
Reviewed-on: https://pdfium-review.googlesource.com/3131
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index c1e9d05..9a03072 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -323,7 +323,6 @@
     "core/fpdfdoc/cpdf_variabletext.h",
     "core/fpdfdoc/cpdf_viewerpreferences.cpp",
     "core/fpdfdoc/cpdf_viewerpreferences.h",
-    "core/fpdfdoc/cpvt_arraytemplate.h",
     "core/fpdfdoc/cpvt_color.cpp",
     "core/fpdfdoc/cpvt_color.h",
     "core/fpdfdoc/cpvt_dash.h",
diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp
index d5746b1..24dd9b0 100644
--- a/core/fpdfdoc/cpdf_variabletext.cpp
+++ b/core/fpdfdoc/cpdf_variabletext.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfdoc/cpdf_variabletext.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fpdfdoc/cline.h"
@@ -113,16 +114,17 @@
 }
 
 bool CPDF_VariableText::Iterator::NextLine() {
-  CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
     return false;
 
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
   if (m_CurPos.nLineIndex <
       pdfium::CollectionSize<int32_t>(pSection->m_LineArray) - 1) {
     m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
     return true;
   }
-  if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
+  if (m_CurPos.nSecIndex <
+      pdfium::CollectionSize<int32_t>(m_pVT->m_SectionArray) - 1) {
     m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
     return true;
   }
@@ -130,20 +132,17 @@
 }
 
 bool CPDF_VariableText::Iterator::PrevLine() {
-  if (!m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex))
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
     return false;
 
   if (m_CurPos.nLineIndex > 0) {
     m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex - 1, -1);
     return true;
   }
-  if (m_CurPos.nSecIndex <= 0)
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex - 1))
     return false;
 
-  CSection* pLastSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex - 1);
-  if (!pLastSection)
-    return false;
-
+  CSection* pLastSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex - 1].get();
   m_CurPos = CPVT_WordPlace(
       m_CurPos.nSecIndex - 1,
       pdfium::CollectionSize<int32_t>(pLastSection->m_LineArray) - 1, -1);
@@ -151,7 +150,8 @@
 }
 
 bool CPDF_VariableText::Iterator::NextSection() {
-  if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
+  if (m_CurPos.nSecIndex <
+      pdfium::CollectionSize<int32_t>(m_pVT->m_SectionArray) - 1) {
     m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
     return true;
   }
@@ -169,12 +169,15 @@
 
 bool CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const {
   word.WordPlace = m_CurPos;
-  CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex);
-  if (!pSection ||
-      !pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex) ||
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
+    return false;
+
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
+  if (!pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex) ||
       !pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex)) {
     return false;
   }
+
   CPVT_WordInfo* pWord = pSection->m_WordArray[m_CurPos.nWordIndex].get();
   word.Word = pWord->Word;
   word.nCharset = pWord->nCharset;
@@ -192,11 +195,13 @@
 }
 
 bool CPDF_VariableText::Iterator::SetWord(const CPVT_Word& word) {
-  CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex);
-  if (!pSection ||
-      !pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex)) {
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
     return false;
-  }
+
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
+  if (!pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex))
+    return false;
+
   CPVT_WordInfo* pWord = pSection->m_WordArray[m_CurPos.nWordIndex].get();
   if (pWord->pWordProps)
     *pWord->pWordProps = word.WordProps;
@@ -206,10 +211,10 @@
 bool CPDF_VariableText::Iterator::GetLine(CPVT_Line& line) const {
   ASSERT(m_pVT);
   line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
-  CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
     return false;
 
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
   if (!pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex))
     return false;
 
@@ -226,22 +231,23 @@
 
 bool CPDF_VariableText::Iterator::GetSection(CPVT_Section& section) const {
   section.secplace = CPVT_WordPlace(m_CurPos.nSecIndex, 0, -1);
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
-    if (pSection->m_SecInfo.pSecProps)
-      section.SecProps = *pSection->m_SecInfo.pSecProps;
-    if (pSection->m_SecInfo.pWordProps)
-      section.WordProps = *pSection->m_SecInfo.pWordProps;
-    return true;
-  }
-  return false;
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
+    return false;
+
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
+  section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
+  if (pSection->m_SecInfo.pSecProps)
+    section.SecProps = *pSection->m_SecInfo.pSecProps;
+  if (pSection->m_SecInfo.pWordProps)
+    section.WordProps = *pSection->m_SecInfo.pWordProps;
+  return true;
 }
 
 bool CPDF_VariableText::Iterator::SetSection(const CPVT_Section& section) {
-  CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
     return false;
 
+  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
   if (pSection->m_SecInfo.pSecProps)
     *pSection->m_SecInfo.pSecProps = section.SecProps;
   if (pSection->m_SecInfo.pWordProps)
@@ -261,7 +267,7 @@
       m_nHorzScale(100),
       m_wSubWord(0),
       m_fFontSize(0.0f),
-      m_bInitial(false),
+      m_bInitialized(false),
       m_pVTProvider(nullptr) {}
 
 CPDF_VariableText::~CPDF_VariableText() {
@@ -269,26 +275,28 @@
 }
 
 void CPDF_VariableText::Initialize() {
-  if (!m_bInitial) {
-    CPVT_SectionInfo secinfo;
-    CPVT_WordPlace place;
-    place.nSecIndex = 0;
-    AddSection(place, secinfo);
-    CPVT_LineInfo lineinfo;
-    lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
-    lineinfo.fLineDescent =
-        GetFontDescent(GetDefaultFontIndex(), GetFontSize());
-    AddLine(place, lineinfo);
-    if (CSection* pSection = m_SectionArray.GetAt(0))
-      pSection->ResetLinePlace();
+  if (m_bInitialized)
+    return;
 
-    m_bInitial = true;
-  }
+  CPVT_SectionInfo secinfo;
+  CPVT_WordPlace place;
+  place.nSecIndex = 0;
+  AddSection(place, secinfo);
+
+  CPVT_LineInfo lineinfo;
+  lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
+  lineinfo.fLineDescent = GetFontDescent(GetDefaultFontIndex(), GetFontSize());
+  AddLine(place, lineinfo);
+
+  if (!m_SectionArray.empty())
+    m_SectionArray.front()->ResetLinePlace();
+
+  m_bInitialized = true;
 }
 
 void CPDF_VariableText::ResetAll() {
-  m_bInitial = false;
-  ResetSectionArray();
+  m_bInitialized = false;
+  m_SectionArray.clear();
 }
 
 CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace& place,
@@ -323,21 +331,23 @@
 
   CPVT_WordPlace wordplace = place;
   UpdateWordPlace(wordplace);
-  CPVT_WordPlace result = place;
-  if (CSection* pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) {
-    CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
-    CPVT_SectionInfo secinfo;
-    AddSection(NewPlace, secinfo);
-    result = NewPlace;
-    if (CSection* pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) {
-      for (int32_t w = wordplace.nWordIndex + 1;
-           w < pdfium::CollectionSize<int32_t>(pSection->m_WordArray); ++w) {
-        NewPlace.nWordIndex++;
-        pNewSection->AddWord(NewPlace, *pSection->m_WordArray[w]);
-      }
+  if (!pdfium::IndexInBounds(m_SectionArray, wordplace.nSecIndex))
+    return place;
+
+  CSection* pSection = m_SectionArray[wordplace.nSecIndex].get();
+  CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
+  CPVT_SectionInfo secinfo;
+  AddSection(NewPlace, secinfo);
+  CPVT_WordPlace result = NewPlace;
+  if (pdfium::IndexInBounds(m_SectionArray, NewPlace.nSecIndex)) {
+    CSection* pNewSection = m_SectionArray[NewPlace.nSecIndex].get();
+    for (int32_t w = wordplace.nWordIndex + 1;
+         w < pdfium::CollectionSize<int32_t>(pSection->m_WordArray); ++w) {
+      NewPlace.nWordIndex++;
+      pNewSection->AddWord(NewPlace, *pSection->m_WordArray[w]);
     }
-    ClearSectionRightWords(wordplace);
   }
+  ClearSectionRightWords(wordplace);
   return result;
 }
 
@@ -379,9 +389,10 @@
 
 CPVT_WordPlace CPDF_VariableText::DeleteWords(
     const CPVT_WordRange& PlaceRange) {
-  bool bLastSecPos = false;
-  if (CSection* pSection = m_SectionArray.GetAt(PlaceRange.EndPos.nSecIndex))
-    bLastSecPos = (PlaceRange.EndPos == pSection->GetEndWordPlace());
+  bool bLastSecPos =
+      pdfium::IndexInBounds(m_SectionArray, PlaceRange.EndPos.nSecIndex) &&
+      PlaceRange.EndPos ==
+          m_SectionArray[PlaceRange.EndPos.nSecIndex]->GetEndWordPlace();
 
   ClearWords(PlaceRange);
   if (PlaceRange.BeginPos.nSecIndex != PlaceRange.EndPos.nSecIndex) {
@@ -404,8 +415,8 @@
   DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
   CPVT_WordPlace wp(0, 0, -1);
   CPVT_SectionInfo secinfo;
-  if (CSection* pSection = m_SectionArray.GetAt(0))
-    pSection->m_SecInfo = secinfo;
+  if (!m_SectionArray.empty())
+    m_SectionArray.front()->m_SecInfo = secinfo;
 
   int32_t nCharCount = 0;
   for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
@@ -451,12 +462,12 @@
 void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
   if (place.nSecIndex < 0)
     place = GetBeginWordPlace();
-  if (place.nSecIndex >= m_SectionArray.GetSize())
+  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
     place = GetEndWordPlace();
 
   place = AdjustLineHeader(place, true);
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
-    pSection->UpdateWordPlace(place);
+  if (pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    m_SectionArray[place.nSecIndex]->UpdateWordPlace(place);
 }
 
 int32_t CPDF_VariableText::WordPlaceToWordIndex(
@@ -466,89 +477,86 @@
   int32_t nIndex = 0;
   int32_t i = 0;
   int32_t sz = 0;
-  for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex;
-       i++) {
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
-      if (i != m_SectionArray.GetSize() - 1)
-        nIndex += kReturnLength;
-    }
+  for (i = 0, sz = pdfium::CollectionSize<int32_t>(m_SectionArray);
+       i < sz && i < newplace.nSecIndex; i++) {
+    CSection* pSection = m_SectionArray[i].get();
+    nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
+    if (i != sz - 1)
+      nIndex += kReturnLength;
   }
-  if (i >= 0 && i < m_SectionArray.GetSize())
+  if (pdfium::IndexInBounds(m_SectionArray, i))
     nIndex += newplace.nWordIndex + kReturnLength;
   return nIndex;
 }
 
 CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const {
   CPVT_WordPlace place = GetBeginWordPlace();
-  int32_t nOldIndex = 0, nIndex = 0;
-  bool bFind = false;
-  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
-      if (nIndex == index) {
-        place = pSection->GetEndWordPlace();
-        bFind = true;
-        break;
-      } else if (nIndex > index) {
-        place.nSecIndex = i;
-        place.nWordIndex = index - nOldIndex - 1;
-        pSection->UpdateWordPlace(place);
-        bFind = true;
-        break;
-      }
-      if (i != m_SectionArray.GetSize() - 1)
-        nIndex += kReturnLength;
-      nOldIndex = nIndex;
+  int32_t nOldIndex = 0;
+  int32_t nIndex = 0;
+  bool bFound = false;
+  for (int32_t i = 0, sz = pdfium::CollectionSize<int32_t>(m_SectionArray);
+       i < sz; i++) {
+    CSection* pSection = m_SectionArray[i].get();
+    nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
+    if (nIndex == index) {
+      place = pSection->GetEndWordPlace();
+      bFound = true;
+      break;
     }
+    if (nIndex > index) {
+      place.nSecIndex = i;
+      place.nWordIndex = index - nOldIndex - 1;
+      pSection->UpdateWordPlace(place);
+      bFound = true;
+      break;
+    }
+    if (i != sz - 1)
+      nIndex += kReturnLength;
+    nOldIndex = nIndex;
   }
-  if (!bFind)
+  if (!bFound)
     place = GetEndWordPlace();
   return place;
 }
 
 CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const {
-  return m_bInitial ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
+  return m_bInitialized ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
 }
 
 CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const {
-  if (CSection* pSection = m_SectionArray.GetAt(m_SectionArray.GetSize() - 1))
-    return pSection->GetEndWordPlace();
-  return CPVT_WordPlace();
+  if (m_SectionArray.empty())
+    return CPVT_WordPlace();
+  return m_SectionArray.back()->GetEndWordPlace();
 }
 
 CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(
     const CPVT_WordPlace& place) const {
   if (place.nSecIndex < 0)
     return GetBeginWordPlace();
-  if (place.nSecIndex >= m_SectionArray.GetSize())
+  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
     return GetEndWordPlace();
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (place.WordCmp(pSection->GetBeginWordPlace()) <= 0) {
-      if (CSection* pPrevSection = m_SectionArray.GetAt(place.nSecIndex - 1))
-        return pPrevSection->GetEndWordPlace();
-      return GetBeginWordPlace();
-    }
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  if (place.WordCmp(pSection->GetBeginWordPlace()) > 0)
     return pSection->GetPrevWordPlace(place);
-  }
-  return place;
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex - 1))
+    return GetBeginWordPlace();
+  return m_SectionArray[place.nSecIndex - 1]->GetEndWordPlace();
 }
 
 CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(
     const CPVT_WordPlace& place) const {
   if (place.nSecIndex < 0)
     return GetBeginWordPlace();
-  if (place.nSecIndex >= m_SectionArray.GetSize())
+  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
     return GetEndWordPlace();
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (place.WordCmp(pSection->GetEndWordPlace()) >= 0) {
-      if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1))
-        return pNextSection->GetBeginWordPlace();
-      return GetEndWordPlace();
-    }
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  if (place.WordCmp(pSection->GetEndWordPlace()) < 0)
     return pSection->GetNextWordPlace(place);
-  }
-  return place;
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex + 1))
+    return GetEndWordPlace();
+  return m_SectionArray[place.nSecIndex + 1]->GetBeginWordPlace();
 }
 
 CPVT_WordPlace CPDF_VariableText::SearchWordPlace(
@@ -556,36 +564,33 @@
   CFX_PointF pt = OutToIn(point);
   CPVT_WordPlace place = GetBeginWordPlace();
   int32_t nLeft = 0;
-  int32_t nRight = m_SectionArray.GetSize() - 1;
-  int32_t nMid = m_SectionArray.GetSize() / 2;
+  int32_t nRight = pdfium::CollectionSize<int32_t>(m_SectionArray) - 1;
+  int32_t nMid = pdfium::CollectionSize<int32_t>(m_SectionArray) / 2;
   bool bUp = true;
   bool bDown = true;
   while (nLeft <= nRight) {
-    if (CSection* pSection = m_SectionArray.GetAt(nMid)) {
-      if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top)) {
-        bUp = false;
-      }
-      if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y)) {
-        bDown = false;
-      }
-      if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
-        nRight = nMid - 1;
-        nMid = (nLeft + nRight) / 2;
-        continue;
-      } else if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
-        nLeft = nMid + 1;
-        nMid = (nLeft + nRight) / 2;
-        continue;
-      } else {
-        place = pSection->SearchWordPlace(
-            CFX_PointF(pt.x - pSection->m_SecInfo.rcSection.left,
-                       pt.y - pSection->m_SecInfo.rcSection.top));
-        place.nSecIndex = nMid;
-        return place;
-      }
-    } else {
+    if (!pdfium::IndexInBounds(m_SectionArray, nMid))
       break;
+    CSection* pSection = m_SectionArray[nMid].get();
+    if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top))
+      bUp = false;
+    if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y))
+      bDown = false;
+    if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
+      nRight = nMid - 1;
+      nMid = (nLeft + nRight) / 2;
+      continue;
     }
+    if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
+      nLeft = nMid + 1;
+      nMid = (nLeft + nRight) / 2;
+      continue;
+    }
+    place = pSection->SearchWordPlace(
+        CFX_PointF(pt.x - pSection->m_SecInfo.rcSection.left,
+                   pt.y - pSection->m_SecInfo.rcSection.top));
+    place.nSecIndex = nMid;
+    return place;
   }
   if (bUp)
     place = GetBeginWordPlace();
@@ -597,20 +602,23 @@
 CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(
     const CPVT_WordPlace& place,
     const CFX_PointF& point) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace temp = place;
-    CFX_PointF pt = OutToIn(point);
-    if (temp.nLineIndex-- > 0) {
-      return pSection->SearchWordPlace(
-          pt.x - pSection->m_SecInfo.rcSection.left, temp);
-    }
-    if (temp.nSecIndex-- > 0) {
-      if (CSection* pLastSection = m_SectionArray.GetAt(temp.nSecIndex)) {
-        temp.nLineIndex =
-            pdfium::CollectionSize<int32_t>(pLastSection->m_LineArray) - 1;
-        return pLastSection->SearchWordPlace(
-            pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
-      }
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    return place;
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  CPVT_WordPlace temp = place;
+  CFX_PointF pt = OutToIn(point);
+  if (temp.nLineIndex-- > 0) {
+    return pSection->SearchWordPlace(pt.x - pSection->m_SecInfo.rcSection.left,
+                                     temp);
+  }
+  if (temp.nSecIndex-- > 0) {
+    if (pdfium::IndexInBounds(m_SectionArray, temp.nSecIndex)) {
+      CSection* pLastSection = m_SectionArray[temp.nSecIndex].get();
+      temp.nLineIndex =
+          pdfium::CollectionSize<int32_t>(pLastSection->m_LineArray) - 1;
+      return pLastSection->SearchWordPlace(
+          pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
     }
   }
   return place;
@@ -619,23 +627,24 @@
 CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(
     const CPVT_WordPlace& place,
     const CFX_PointF& point) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace temp = place;
-    CFX_PointF pt = OutToIn(point);
-    if (temp.nLineIndex++ <
-        pdfium::CollectionSize<int32_t>(pSection->m_LineArray) - 1) {
-      return pSection->SearchWordPlace(
-          pt.x - pSection->m_SecInfo.rcSection.left, temp);
-    }
-    if (temp.nSecIndex++ < m_SectionArray.GetSize() - 1) {
-      if (CSection* pNextSection = m_SectionArray.GetAt(temp.nSecIndex)) {
-        temp.nLineIndex = 0;
-        return pNextSection->SearchWordPlace(
-            pt.x - pSection->m_SecInfo.rcSection.left, temp);
-      }
-    }
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    return place;
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  CPVT_WordPlace temp = place;
+  CFX_PointF pt = OutToIn(point);
+  if (temp.nLineIndex++ <
+      pdfium::CollectionSize<int32_t>(pSection->m_LineArray) - 1) {
+    return pSection->SearchWordPlace(pt.x - pSection->m_SecInfo.rcSection.left,
+                                     temp);
   }
-  return place;
+  ++temp.nSecIndex;
+  temp.nLineIndex = 0;
+  if (!pdfium::IndexInBounds(m_SectionArray, temp.nSecIndex))
+    return place;
+
+  return m_SectionArray[temp.nSecIndex]->SearchWordPlace(
+      pt.x - pSection->m_SecInfo.rcSection.left, temp);
 }
 
 CPVT_WordPlace CPDF_VariableText::GetLineBeginPlace(
@@ -645,10 +654,10 @@
 
 CPVT_WordPlace CPDF_VariableText::GetLineEndPlace(
     const CPVT_WordPlace& place) const {
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return place;
 
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
   if (!pdfium::IndexInBounds(pSection->m_LineArray, place.nLineIndex))
     return place;
 
@@ -662,97 +671,89 @@
 
 CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace(
     const CPVT_WordPlace& place) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
-    return pSection->GetEndWordPlace();
-  return place;
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    return place;
+
+  return m_SectionArray[place.nSecIndex]->GetEndWordPlace();
 }
 
 int32_t CPDF_VariableText::GetTotalWords() const {
   int32_t nTotal = 0;
-  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nTotal += pdfium::CollectionSize<int32_t>(pSection->m_WordArray) +
-                kReturnLength;
-    }
+  for (const auto& pSection : m_SectionArray) {
+    nTotal +=
+        pdfium::CollectionSize<int32_t>(pSection->m_WordArray) + kReturnLength;
   }
   return nTotal - kReturnLength;
 }
 
-void CPDF_VariableText::ResetSectionArray() {
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++)
-    delete m_SectionArray.GetAt(s);
-
-  m_SectionArray.RemoveAll();
-}
-
 CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace& place,
                                              const CPVT_SectionInfo& secinfo) {
   if (IsValid() && !m_bMultiLine)
     return place;
 
-  int32_t nSecIndex =
-      pdfium::clamp(place.nSecIndex, 0, m_SectionArray.GetSize());
-  CSection* pSection = new CSection(this);
+  int32_t nSecIndex = pdfium::clamp(
+      place.nSecIndex, 0, pdfium::CollectionSize<int32_t>(m_SectionArray));
+
+  auto pSection = pdfium::MakeUnique<CSection>(this);
   pSection->m_SecInfo = secinfo;
   pSection->SecPlace.nSecIndex = nSecIndex;
-  if (nSecIndex == m_SectionArray.GetSize())
-    m_SectionArray.Add(pSection);
-  else
-    m_SectionArray.InsertAt(nSecIndex, pSection);
-
+  m_SectionArray.insert(m_SectionArray.begin() + nSecIndex,
+                        std::move(pSection));
   return place;
 }
 
 CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace& place,
                                           const CPVT_LineInfo& lineinfo) {
-  if (m_SectionArray.IsEmpty())
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return place;
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
-    return pSection->AddLine(lineinfo);
-  return place;
+
+  return m_SectionArray[place.nSecIndex]->AddLine(lineinfo);
 }
 
 CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place,
                                           const CPVT_WordInfo& wordinfo) {
-  if (m_SectionArray.GetSize() <= 0) {
+  if (m_SectionArray.empty())
     return place;
-  }
+
   CPVT_WordPlace newplace = place;
   newplace.nSecIndex =
-      pdfium::clamp(newplace.nSecIndex, 0, m_SectionArray.GetSize() - 1);
-  if (CSection* pSection = m_SectionArray.GetAt(newplace.nSecIndex))
-    return pSection->AddWord(newplace, wordinfo);
-  return place;
+      pdfium::clamp(newplace.nSecIndex, 0,
+                    pdfium::CollectionSize<int32_t>(m_SectionArray) - 1);
+  return m_SectionArray[newplace.nSecIndex]->AddWord(newplace, wordinfo);
 }
 
 bool CPDF_VariableText::GetWordInfo(const CPVT_WordPlace& place,
                                     CPVT_WordInfo& wordinfo) {
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection ||
-      !pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex)) {
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return false;
-  }
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  if (!pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex))
+    return false;
+
   wordinfo = *pSection->m_WordArray[place.nWordIndex];
   return true;
 }
 
 bool CPDF_VariableText::SetWordInfo(const CPVT_WordPlace& place,
                                     const CPVT_WordInfo& wordinfo) {
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection ||
-      !pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex)) {
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return false;
-  }
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  if (!pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex))
+    return false;
+
   *pSection->m_WordArray[place.nWordIndex] = wordinfo;
   return true;
 }
 
 bool CPDF_VariableText::GetLineInfo(const CPVT_WordPlace& place,
                                     CPVT_LineInfo& lineinfo) {
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return false;
 
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
   if (!pdfium::IndexInBounds(pSection->m_LineArray, place.nLineIndex))
     return false;
 
@@ -762,11 +763,11 @@
 
 bool CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace& place,
                                        CPVT_SectionInfo& secinfo) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    secinfo = pSection->m_SecInfo;
-    return true;
-  }
-  return false;
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    return false;
+
+  secinfo = m_SectionArray[place.nSecIndex]->m_SecInfo;
+  return true;
 }
 
 void CPDF_VariableText::SetPlateRect(const CFX_FloatRect& rect) {
@@ -868,11 +869,13 @@
 
 void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
   CPVT_WordPlace wordplace = AdjustLineHeader(place, true);
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection ||
-      !pdfium::IndexInBounds(pSection->m_WordArray, wordplace.nWordIndex + 1)) {
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return;
-  }
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  if (!pdfium::IndexInBounds(pSection->m_WordArray, wordplace.nWordIndex + 1))
+    return;
+
   pSection->m_WordArray.erase(
       pSection->m_WordArray.begin() + wordplace.nWordIndex + 1,
       pSection->m_WordArray.end());
@@ -886,15 +889,16 @@
 }
 
 bool CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
-  if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1)
+  if (place.nSecIndex == 0 && m_SectionArray.size() == 1)
     return false;
 
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection || !pSection->m_WordArray.empty())
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return false;
 
-  delete pSection;
-  m_SectionArray.RemoveAt(place.nSecIndex);
+  if (!m_SectionArray[place.nSecIndex]->m_WordArray.empty())
+    return false;
+
+  m_SectionArray.erase(m_SectionArray.begin() + place.nSecIndex);
   return true;
 }
 
@@ -909,16 +913,18 @@
 
 void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace& place) {
   CPVT_WordPlace oldplace = AdjustLineHeader(place, true);
-  if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
-    if (CSection* pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) {
-      for (auto& pWord : pNextSection->m_WordArray) {
-        oldplace.nWordIndex++;
-        pSection->AddWord(oldplace, *pWord);
-      }
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex + 1))
+    return;
+
+  CSection* pNextSection = m_SectionArray[place.nSecIndex + 1].get();
+  if (pdfium::IndexInBounds(m_SectionArray, oldplace.nSecIndex)) {
+    CSection* pSection = m_SectionArray[oldplace.nSecIndex].get();
+    for (auto& pWord : pNextSection->m_WordArray) {
+      oldplace.nWordIndex++;
+      pSection->AddWord(oldplace, *pWord);
     }
-    delete pNextSection;
-    m_SectionArray.RemoveAt(place.nSecIndex + 1);
   }
+  m_SectionArray.erase(m_SectionArray.begin() + place.nSecIndex + 1);
 }
 
 void CPDF_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) {
@@ -927,16 +933,16 @@
   NewRange.EndPos = AdjustLineHeader(PlaceRange.EndPos, true);
   for (int32_t s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex;
        s--) {
-    if (CSection* pSection = m_SectionArray.GetAt(s))
-      pSection->ClearWords(NewRange);
+    if (pdfium::IndexInBounds(m_SectionArray, s))
+      m_SectionArray[s]->ClearWords(NewRange);
   }
 }
 
 CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
-  CSection* pSection = m_SectionArray.GetAt(place.nSecIndex);
-  if (!pSection)
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
     return place;
 
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
   CPVT_WordPlace leftplace = GetPrevWordPlace(place);
   if (leftplace == place)
     return place;
@@ -953,16 +959,18 @@
 }
 
 CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace rightplace =
-        AdjustLineHeader(GetNextWordPlace(place), false);
-    if (rightplace != place) {
-      if (rightplace.nSecIndex != place.nSecIndex)
-        LinkLatterSection(place);
-      else
-        pSection->ClearWord(rightplace);
-    }
-  }
+  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
+    return place;
+
+  CSection* pSection = m_SectionArray[place.nSecIndex].get();
+  CPVT_WordPlace rightplace = AdjustLineHeader(GetNextWordPlace(place), false);
+  if (rightplace == place)
+    return place;
+
+  if (rightplace.nSecIndex != place.nSecIndex)
+    LinkLatterSection(place);
+  else
+    pSection->ClearWord(rightplace);
   return place;
 }
 
@@ -1017,15 +1025,13 @@
 
 bool CPDF_VariableText::IsBigger(float fFontSize) const {
   CFX_SizeF szTotal;
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
-    if (CSection* pSection = m_SectionArray.GetAt(s)) {
-      CFX_SizeF size = pSection->GetSectionSize(fFontSize);
-      szTotal.width = std::max(size.width, szTotal.width);
-      szTotal.height += size.height;
-      if (IsFloatBigger(szTotal.width, GetPlateWidth()) ||
-          IsFloatBigger(szTotal.height, GetPlateHeight())) {
-        return true;
-      }
+  for (const auto& pSection : m_SectionArray) {
+    CFX_SizeF size = pSection->GetSectionSize(fFontSize);
+    szTotal.width = std::max(size.width, szTotal.width);
+    szTotal.height += size.height;
+    if (IsFloatBigger(szTotal.width, GetPlateWidth()) ||
+        IsFloatBigger(szTotal.height, GetPlateHeight())) {
+      return true;
     }
   }
   return false;
@@ -1039,35 +1045,35 @@
   int32_t nSSecIndex = PlaceRange.BeginPos.nSecIndex;
   int32_t nESecIndex = PlaceRange.EndPos.nSecIndex;
   CPVT_FloatRect rcRet;
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
+  for (int32_t s = 0, sz = pdfium::CollectionSize<int32_t>(m_SectionArray);
+       s < sz; s++) {
     place.nSecIndex = s;
-    if (CSection* pSection = m_SectionArray.GetAt(s)) {
-      pSection->SecPlace = place;
-      CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
-      if (s >= nSSecIndex) {
-        if (s <= nESecIndex) {
-          rcSec = pSection->Rearrange();
-          rcSec.top += fPosY;
-          rcSec.bottom += fPosY;
-        } else {
-          fOldHeight = pSection->m_SecInfo.rcSection.bottom -
-                       pSection->m_SecInfo.rcSection.top;
-          rcSec.top = fPosY;
-          rcSec.bottom = fPosY + fOldHeight;
-        }
-        pSection->m_SecInfo.rcSection = rcSec;
-        pSection->ResetLinePlace();
-      }
-      if (s == 0) {
-        rcRet = rcSec;
+    CSection* pSection = m_SectionArray[s].get();
+    pSection->SecPlace = place;
+    CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
+    if (s >= nSSecIndex) {
+      if (s <= nESecIndex) {
+        rcSec = pSection->Rearrange();
+        rcSec.top += fPosY;
+        rcSec.bottom += fPosY;
       } else {
-        rcRet.left = std::min(rcSec.left, rcRet.left);
-        rcRet.top = std::min(rcSec.top, rcRet.top);
-        rcRet.right = std::max(rcSec.right, rcRet.right);
-        rcRet.bottom = std::max(rcSec.bottom, rcRet.bottom);
+        fOldHeight = pSection->m_SecInfo.rcSection.bottom -
+                     pSection->m_SecInfo.rcSection.top;
+        rcSec.top = fPosY;
+        rcSec.bottom = fPosY + fOldHeight;
       }
-      fPosY += rcSec.Height();
+      pSection->m_SecInfo.rcSection = rcSec;
+      pSection->ResetLinePlace();
     }
+    if (s == 0) {
+      rcRet = rcSec;
+    } else {
+      rcRet.left = std::min(rcSec.left, rcRet.left);
+      rcRet.top = std::min(rcSec.top, rcRet.top);
+      rcRet.right = std::max(rcSec.right, rcRet.right);
+      rcRet.bottom = std::max(rcSec.bottom, rcRet.bottom);
+    }
+    fPosY += rcSec.Height();
   }
   return rcRet;
 }
diff --git a/core/fpdfdoc/cpdf_variabletext.h b/core/fpdfdoc/cpdf_variabletext.h
index 59fe124..2e6caf6 100644
--- a/core/fpdfdoc/cpdf_variabletext.h
+++ b/core/fpdfdoc/cpdf_variabletext.h
@@ -8,8 +8,8 @@
 #define CORE_FPDFDOC_CPDF_VARIABLETEXT_H_
 
 #include <memory>
+#include <vector>
 
-#include "core/fpdfdoc/cpvt_arraytemplate.h"
 #include "core/fpdfdoc/cpvt_floatrect.h"
 #include "core/fpdfdoc/cpvt_line.h"
 #include "core/fpdfdoc/cpvt_lineinfo.h"
@@ -101,7 +101,7 @@
   void SetAutoFontSize(bool bAuto) { m_bAutoFontSize = bAuto; }
   void Initialize();
 
-  bool IsValid() const { return m_bInitial; }
+  bool IsValid() const { return m_bInitialized; }
 
   void RearrangeAll();
   void RearrangePart(const CPVT_WordRange& PlaceRange);
@@ -219,9 +219,7 @@
   bool IsBigger(float fFontSize) const;
   CPVT_FloatRect RearrangeSections(const CPVT_WordRange& PlaceRange);
 
-  void ResetSectionArray();
-
-  CPVT_ArrayTemplate<CSection*> m_SectionArray;
+  std::vector<std::unique_ptr<CSection>> m_SectionArray;
   int32_t m_nLimitChar;
   int32_t m_nCharArray;
   bool m_bMultiLine;
@@ -233,7 +231,7 @@
   int32_t m_nHorzScale;
   uint16_t m_wSubWord;
   float m_fFontSize;
-  bool m_bInitial;
+  bool m_bInitialized;
   CPDF_VariableText::Provider* m_pVTProvider;
   std::unique_ptr<CPDF_VariableText::Iterator> m_pVTIterator;
   CFX_FloatRect m_rcPlate;
diff --git a/core/fpdfdoc/cpvt_arraytemplate.h b/core/fpdfdoc/cpvt_arraytemplate.h
deleted file mode 100644
index 5274bd9..0000000
--- a/core/fpdfdoc/cpvt_arraytemplate.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_
-#define CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_
-
-#include "core/fxcrt/fx_basic.h"
-#include "core/fxcrt/fx_system.h"
-
-template <class TYPE>
-class CPVT_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
- public:
-  bool IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
-
-  TYPE GetAt(int nIndex) const {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
-      return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
-    return nullptr;
-  }
-
-  void RemoveAt(int nIndex) {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
-      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
-  }
-};
-
-#endif  // CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_