Use std::vector for fx_ucd.h arrays.

Review-Url: https://codereview.chromium.org/2650773003
diff --git a/core/fxcrt/fx_arabic.cpp b/core/fxcrt/fx_arabic.cpp
index a649e49..108c6c1 100644
--- a/core/fxcrt/fx_arabic.cpp
+++ b/core/fxcrt/fx_arabic.cpp
@@ -5,7 +5,12 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "core/fxcrt/fx_arabic.h"
+
+#include <algorithm>
+#include <vector>
+
 #include "core/fxcrt/fx_ucd.h"
+#include "third_party/base/stl_util.h"
 
 namespace {
 
@@ -419,81 +424,62 @@
 template <class baseType>
 class CFX_BidiLineTemplate {
  public:
-  void FX_BidiReverseString(CFX_ArrayTemplate<baseType>& chars,
+  void FX_BidiReverseString(std::vector<baseType>& chars,
                             int32_t iStart,
                             int32_t iCount) {
-    ASSERT(iStart > -1 && iStart < chars.GetSize());
-    ASSERT(iCount >= 0 && iStart + iCount <= chars.GetSize());
-    baseType *pStart, *pEnd;
-    int32_t iEnd = iStart + iCount - 1, iTemp;
-    while (iStart < iEnd) {
-      pStart = chars.GetDataPtr(iStart++);
-      pEnd = chars.GetDataPtr(iEnd--);
-      iTemp = pStart->m_iBidiPos;
-      pStart->m_iBidiPos = pEnd->m_iBidiPos;
-      pEnd->m_iBidiPos = iTemp;
-    }
+    ASSERT(iStart >= 0 && iStart < pdfium::CollectionSize<int32_t>(chars));
+    ASSERT(iCount >= 0 &&
+           iStart + iCount <= pdfium::CollectionSize<int32_t>(chars));
+    std::reverse(chars.begin() + iStart, chars.begin() + iStart + iCount);
   }
-  void FX_BidiSetDeferredRun(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiSetDeferredRun(std::vector<baseType>& chars,
                              bool bClass,
                              int32_t iStart,
                              int32_t iCount,
                              int32_t iValue) {
-    ASSERT(iStart > -1 && iStart <= chars.GetSize());
+    ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iStart - iCount > -1);
-    baseType* pTC;
     int32_t iLast = iStart - iCount;
     if (bClass) {
-      for (int32_t i = iStart - 1; i >= iLast; i--) {
-        pTC = chars.GetDataPtr(i);
-        pTC->m_iBidiClass = (int16_t)iValue;
-      }
+      for (int32_t i = iStart - 1; i >= iLast; i--)
+        chars[i].m_iBidiClass = (int16_t)iValue;
     } else {
-      for (int32_t i = iStart - 1; i >= iLast; i--) {
-        pTC = chars.GetDataPtr(i);
-        pTC->m_iBidiLevel = (int16_t)iValue;
-      }
+      for (int32_t i = iStart - 1; i >= iLast; i--)
+        chars[i].m_iBidiLevel = (int16_t)iValue;
     }
   }
-  void FX_BidiClassify(CFX_ArrayTemplate<baseType>& chars,
-                       int32_t iCount,
-                       bool bWS) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
-    baseType* pTC;
+
+  void FX_BidiClassify(std::vector<baseType>& chars, int32_t iCount, bool bWS) {
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     if (bWS) {
       for (int32_t i = 0; i < iCount; i++) {
-        pTC = chars.GetDataPtr(i);
-        pTC->m_iBidiClass =
-            (int16_t)(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >>
+        chars[i].m_iBidiClass =
+            (int16_t)(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >>
             FX_BIDICLASSBITS;
       }
     } else {
       for (int32_t i = 0; i < iCount; i++) {
-        pTC = chars.GetDataPtr(i);
-        pTC->m_iBidiClass = (int16_t)
-            gc_FX_BidiNTypes[(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >>
+        chars[i].m_iBidiClass = (int16_t)
+            gc_FX_BidiNTypes[(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >>
                              FX_BIDICLASSBITS];
       }
     }
   }
-  void FX_BidiResolveExplicit(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiResolveExplicit(std::vector<baseType>& chars,
                               int32_t iCount,
                               int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
-    if (iCount < 1) {
-      return;
-    }
-    baseType* pTC;
-    for (int32_t i = 0; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
-      pTC->m_iBidiLevel = (int16_t)iBaseLevel;
-    }
+    for (int32_t i = 0; i < iCount; i++)
+      chars[i].m_iBidiLevel = static_cast<int16_t>(iBaseLevel);
   }
-  void FX_BidiResolveWeak(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiResolveWeak(std::vector<baseType>& chars,
                           int32_t iCount,
                           int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     iCount--;
     if (iCount < 1) {
       return;
@@ -503,7 +489,7 @@
     int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BWSxr : FX_BWSxl;
     int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
     for (; i <= iCount; i++) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       iClsCur = pTC->m_iBidiClass;
       if (iClsCur == FX_BIDICLASS_BN) {
         pTC->m_iBidiLevel = (int16_t)iLevelCur;
@@ -511,7 +497,7 @@
           iClsCur = FX_BidiDirection(iLevelCur);
           pTC->m_iBidiClass = (int16_t)iClsCur;
         } else if (i < iCount) {
-          pTCNext = chars.GetDataPtr(i + 1);
+          pTCNext = &chars[i + 1];
           int32_t iLevelNext, iLevelNew;
           iClsNew = pTCNext->m_iBidiClass;
           iLevelNext = pTCNext->m_iBidiLevel;
@@ -561,10 +547,11 @@
       }
     }
   }
-  void FX_BidiResolveNeutrals(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiResolveNeutrals(std::vector<baseType>& chars,
                               int32_t iCount,
                               int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
     iCount--;
     if (iCount < 1) {
@@ -575,7 +562,7 @@
     int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BNSr : FX_BNSl;
     int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
     for (; i <= iCount; i++) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       iClsCur = pTC->m_iBidiClass;
       if (iClsCur == FX_BIDICLASS_BN) {
         if (iNum) {
@@ -609,27 +596,25 @@
       }
     }
   }
-  void FX_BidiResolveImplicit(CFX_ArrayTemplate<baseType>& chars,
-                              int32_t iCount) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
-    baseType* pTC;
-    int32_t iCls, iLevel;
+
+  void FX_BidiResolveImplicit(std::vector<baseType>& chars, int32_t iCount) {
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     for (int32_t i = 0; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
-      iCls = pTC->m_iBidiClass;
+      int32_t iCls = chars[i].m_iBidiClass;
       if (iCls == FX_BIDICLASS_BN) {
         continue;
       }
       ASSERT(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL);
-      iLevel = pTC->m_iBidiLevel;
+      int32_t iLevel = chars[i].m_iBidiLevel;
       iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
-      pTC->m_iBidiLevel = (int16_t)iLevel;
+      chars[i].m_iBidiLevel = (int16_t)iLevel;
     }
   }
-  void FX_BidiResolveWhitespace(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiResolveWhitespace(std::vector<baseType>& chars,
                                 int32_t iCount,
                                 int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
     if (iCount < 1) {
       return;
@@ -637,10 +622,8 @@
     iCount--;
     int32_t iLevel = iBaseLevel;
     int32_t i = 0, iNum = 0;
-    baseType* pTC;
     for (; i <= iCount; i++) {
-      pTC = chars.GetDataPtr(i);
-      switch (pTC->m_iBidiClass) {
+      switch (chars[i].m_iBidiClass) {
         case FX_BIDICLASS_WS:
           iNum++;
           break;
@@ -650,7 +633,7 @@
         case FX_BIDICLASS_RLO:
         case FX_BIDICLASS_PDF:
         case FX_BIDICLASS_BN:
-          pTC->m_iBidiLevel = (int16_t)iLevel;
+          chars[i].m_iBidiLevel = (int16_t)iLevel;
           iNum++;
           break;
         case FX_BIDICLASS_S:
@@ -658,41 +641,39 @@
           if (iNum > 0) {
             FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel);
           }
-          pTC->m_iBidiLevel = (int16_t)iBaseLevel;
+          chars[i].m_iBidiLevel = (int16_t)iBaseLevel;
           iNum = 0;
           break;
         default:
           iNum = 0;
           break;
       }
-      iLevel = pTC->m_iBidiLevel;
+      iLevel = chars[i].m_iBidiLevel;
     }
     if (iNum > 0) {
       FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel);
     }
   }
-  int32_t FX_BidiReorderLevel(CFX_ArrayTemplate<baseType>& chars,
+
+  int32_t FX_BidiReorderLevel(std::vector<baseType>& chars,
                               int32_t iCount,
                               int32_t iBaseLevel,
                               int32_t iStart,
                               bool bReverse) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
     ASSERT(iStart >= 0 && iStart < iCount);
     if (iCount < 1) {
       return 0;
     }
-    baseType* pTC;
     bReverse = bReverse || FX_IsOdd(iBaseLevel);
-    int32_t i = iStart, iLevel;
+    int32_t i = iStart;
     for (; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
-      if ((iLevel = pTC->m_iBidiLevel) == iBaseLevel) {
+      int32_t iLevel = chars[i].m_iBidiLevel;
+      if (iLevel == iBaseLevel)
         continue;
-      }
-      if (iLevel < iBaseLevel) {
+      if (iLevel < iBaseLevel)
         break;
-      }
       i += FX_BidiReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
     }
     int32_t iNum = i - iStart;
@@ -701,31 +682,28 @@
     }
     return iNum;
   }
-  void FX_BidiReorder(CFX_ArrayTemplate<baseType>& chars,
+
+  void FX_BidiReorder(std::vector<baseType>& chars,
                       int32_t iCount,
                       int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
     int32_t i = 0;
     while (i < iCount) {
       i += FX_BidiReorderLevel(chars, iCount, iBaseLevel, i, false);
     }
   }
-  void FX_BidiPosition(CFX_ArrayTemplate<baseType>& chars, int32_t iCount) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
-    baseType* pTC;
-    int32_t i = 0;
-    while (i < iCount) {
-      pTC = chars.GetDataPtr(i);
-      pTC = chars.GetDataPtr(pTC->m_iBidiPos);
-      pTC->m_iBidiOrder = i++;
-    }
+
+  void FX_BidiPosition(std::vector<baseType>& chars, int32_t iCount) {
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+    for (int32_t i = 0; i < iCount; ++i)
+      chars[chars[i].m_iBidiPos].m_iBidiOrder = i;
   }
 
-  void FX_BidiLine(CFX_ArrayTemplate<baseType>& chars,
+  void FX_BidiLine(std::vector<baseType>& chars,
                    int32_t iCount,
                    int32_t iBaseLevel) {
-    ASSERT(iCount > -1 && iCount <= chars.GetSize());
+    ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
     if (iCount < 2) {
       return;
     }
@@ -740,11 +718,16 @@
     FX_BidiPosition(chars, iCount);
   }
 };
-void FX_BidiLine(CFX_TxtCharArray& chars, int32_t iCount, int32_t iBaseLevel) {
+
+void FX_BidiLine(std::vector<CFX_TxtChar>& chars,
+                 int32_t iCount,
+                 int32_t iBaseLevel) {
   CFX_BidiLineTemplate<CFX_TxtChar> blt;
   blt.FX_BidiLine(chars, iCount, iBaseLevel);
 }
-void FX_BidiLine(CFX_RTFCharArray& chars, int32_t iCount, int32_t iBaseLevel) {
+void FX_BidiLine(std::vector<CFX_RTFChar>& chars,
+                 int32_t iCount,
+                 int32_t iBaseLevel) {
   CFX_BidiLineTemplate<CFX_RTFChar> blt;
   blt.FX_BidiLine(chars, iCount, iBaseLevel);
 }
diff --git a/core/fxcrt/fx_arb.h b/core/fxcrt/fx_arb.h
index 6d556fe..d24197c 100644
--- a/core/fxcrt/fx_arb.h
+++ b/core/fxcrt/fx_arb.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FXCRT_FX_ARB_H_
 #define CORE_FXCRT_FX_ARB_H_
 
+#include <vector>
+
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/fx_ucd.h"
 
@@ -39,10 +41,10 @@
 };
 
 void FX_BidiLine(CFX_WideString& wsText, int32_t iBaseLevel = 0);
-void FX_BidiLine(CFX_TxtCharArray& chars,
+void FX_BidiLine(std::vector<CFX_TxtChar>& chars,
                  int32_t iCount,
                  int32_t iBaseLevel = 0);
-void FX_BidiLine(CFX_RTFCharArray& chars,
+void FX_BidiLine(std::vector<CFX_RTFChar>& chars,
                  int32_t iCount,
                  int32_t iBaseLevel = 0);
 
diff --git a/core/fxcrt/fx_ucd.h b/core/fxcrt/fx_ucd.h
index d79693b..798658f 100644
--- a/core/fxcrt/fx_ucd.h
+++ b/core/fxcrt/fx_ucd.h
@@ -148,7 +148,7 @@
   int32_t m_iHorizontalScale;
   int32_t m_iVertialScale;
 };
-typedef CFX_ArrayTemplate<CFX_Char> CFX_CharArray;
+
 class CFX_TxtChar : public CFX_Char {
  public:
   CFX_TxtChar()
@@ -165,7 +165,7 @@
   int16_t m_iBidiOrder;
   void* m_pUserData;
 };
-typedef CFX_ArrayTemplate<CFX_TxtChar> CFX_TxtCharArray;
+
 class CFX_RTFChar : public CFX_Char {
  public:
   CFX_RTFChar();
@@ -196,7 +196,6 @@
 
 inline CFX_RTFChar::CFX_RTFChar(const CFX_RTFChar& other) = default;
 
-typedef CFX_ArrayTemplate<CFX_RTFChar> CFX_RTFCharArray;
 #endif  // PDF_ENABLE_XFA
 
 #endif  // CORE_FXCRT_FX_UCD_H_
diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp
index 52e6267..e01578b 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.cpp
+++ b/xfa/fgas/layout/fgas_rtfbreak.cpp
@@ -273,15 +273,14 @@
   }
 }
 CFX_RTFChar* CFX_RTFBreak::GetLastChar(int32_t index) const {
-  CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
-  int32_t iCount = tca.GetSize();
+  std::vector<CFX_RTFChar>& tca = m_pCurLine->m_LineChars;
+  int32_t iCount = pdfium::CollectionSize<int32_t>(tca);
   if (index < 0 || index >= iCount) {
     return nullptr;
   }
-  CFX_RTFChar* pTC;
   int32_t iStart = iCount - 1;
   while (iStart > -1) {
-    pTC = tca.GetDataPtr(iStart--);
+    CFX_RTFChar* pTC = &tca[iStart--];
     if (pTC->m_iCharWidth >= 0 ||
         pTC->GetCharType() != FX_CHARTYPE_Combination) {
       if (--index < 0) {
@@ -349,8 +348,8 @@
 
   uint32_t dwProps = kTextLayoutCodeProperties[(uint16_t)wch];
   FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps);
-  CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
-  CFX_RTFChar* pCurChar = tca.AddSpace();
+  m_pCurLine->m_LineChars.emplace_back();
+  CFX_RTFChar* pCurChar = &m_pCurLine->m_LineChars.back();
   pCurChar->m_dwStatus = 0;
   pCurChar->m_wCharCode = wch;
   pCurChar->m_dwCharProps = dwProps;
@@ -377,7 +376,7 @@
         dwRet1 = EndBreak(FX_RTFBREAK_LineBreak);
         int32_t iCount = m_pCurLine->CountChars();
         if (iCount > 0) {
-          pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1);
+          pCurChar = &m_pCurLine->m_LineChars[iCount - 1];
         }
       }
     }
@@ -397,8 +396,8 @@
   ASSERT(m_pFont && m_pCurLine);
   ASSERT(m_bCharCode);
   m_pCurLine->m_iMBCSChars++;
-  CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
-  CFX_RTFChar* pCurChar = tca.AddSpace();
+  m_pCurLine->m_LineChars.emplace_back();
+  CFX_RTFChar* pCurChar = &m_pCurLine->m_LineChars.back();
   pCurChar->m_dwStatus = 0;
   pCurChar->m_wCharCode = wch;
   pCurChar->m_dwCharProps = 0;
@@ -696,7 +695,7 @@
     }
   }
   if (m_bPagination || m_pCurLine->m_iMBCSChars > 0) {
-    const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.GetData();
+    const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.data();
     const CFX_RTFChar* pTC;
     CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
     CFX_RTFPiece tp;
@@ -751,14 +750,14 @@
   CFX_RTFPiece tp;
   CFX_RTFChar* pTC;
   int32_t i, j;
-  CFX_RTFCharArray& chars = m_pCurLine->m_LineChars;
+  std::vector<CFX_RTFChar>& chars = m_pCurLine->m_LineChars;
   int32_t iCount = m_pCurLine->CountChars();
   bool bDone = (!m_bPagination && !m_bCharCode &&
                 (m_pCurLine->m_iArabicChars > 0 || m_bRTL));
   if (bDone) {
     int32_t iBidiNum = 0;
     for (i = 0; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       pTC->m_iBidiPos = i;
       if (pTC->GetCharType() != FX_CHARTYPE_Control) {
         iBidiNum = i;
@@ -770,7 +769,7 @@
     FX_BidiLine(chars, iBidiNum + 1, m_bRTL ? 1 : 0);
   } else {
     for (i = 0; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       pTC->m_iBidiLevel = 0;
       pTC->m_iBidiPos = 0;
       pTC->m_iBidiOrder = 0;
@@ -784,7 +783,7 @@
   uint32_t dwIdentity = (uint32_t)-1;
   i = j = 0;
   while (i < iCount) {
-    pTC = chars.GetDataPtr(i);
+    pTC = &chars[i];
     if (iBidiLevel < 0) {
       iBidiLevel = pTC->m_iBidiLevel;
       iCharWidth = pTC->m_iCharWidth;
@@ -933,11 +932,11 @@
   }
 }
 
-int32_t CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray& tca,
+int32_t CFX_RTFBreak::GetBreakPos(std::vector<CFX_RTFChar>& tca,
                                   int32_t& iEndPos,
                                   bool bAllChars,
                                   bool bOnlyBrk) {
-  int32_t iLength = tca.GetSize() - 1;
+  int32_t iLength = pdfium::CollectionSize<int32_t>(tca) - 1;
   if (iLength < 1)
     return iLength;
 
@@ -950,7 +949,7 @@
     iBreak = iLength;
     iBreakPos = iEndPos;
   }
-  CFX_RTFChar* pCharArray = tca.GetData();
+  CFX_RTFChar* pCharArray = tca.data();
   if (m_bCharCode) {
     const CFX_RTFChar* pChar;
     int32_t iCharWidth;
@@ -1071,7 +1070,7 @@
     return;
   }
   int32_t iEndPos = pCurLine->GetLineEnd();
-  CFX_RTFCharArray& curChars = pCurLine->m_LineChars;
+  std::vector<CFX_RTFChar>& curChars = pCurLine->m_LineChars;
   int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, false);
   if (iCharPos < 0) {
     iCharPos = 0;
@@ -1079,24 +1078,20 @@
   iCharPos++;
   if (iCharPos >= iCount) {
     pNextLine->RemoveAll(true);
-    CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
+    CFX_Char* pTC = &curChars[iCharPos - 1];
     pTC->m_nBreakType = FX_LBT_UNKNOWN;
     return;
   }
-  CFX_RTFCharArray& nextChars = pNextLine->m_LineChars;
-  int cur_size = curChars.GetSize();
-  nextChars.SetSize(cur_size - iCharPos);
-  FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
-               (cur_size - iCharPos) * sizeof(CFX_RTFChar));
-  iCount -= iCharPos;
-  cur_size = curChars.GetSize();
-  curChars.RemoveAt(cur_size - iCount, iCount);
+  std::vector<CFX_RTFChar>& nextChars = pNextLine->m_LineChars;
+  nextChars =
+      std::vector<CFX_RTFChar>(curChars.begin() + iCharPos, curChars.end());
+  curChars.erase(curChars.begin() + iCharPos, curChars.end());
   pNextLine->m_iStart = pCurLine->m_iStart;
   pNextLine->m_iWidth = pCurLine->GetLineEnd() - iEndPos;
   pCurLine->m_iWidth = iEndPos;
-  curChars.GetDataPtr(iCharPos - 1)->m_nBreakType = FX_LBT_UNKNOWN;
-  iCount = nextChars.GetSize();
-  CFX_RTFChar* pNextChars = nextChars.GetData();
+  curChars[iCharPos - 1].m_nBreakType = FX_LBT_UNKNOWN;
+  iCount = pdfium::CollectionSize<int>(nextChars);
+  CFX_RTFChar* pNextChars = nextChars.data();
   for (int32_t i = 0; i < iCount; i++) {
     CFX_RTFChar* tc = pNextChars + i;
     if (tc->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h
index f3d2311..613156a 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.h
+++ b/xfa/fgas/layout/fgas_rtfbreak.h
@@ -89,7 +89,7 @@
 
   void AppendChar(const CFX_RTFChar& tc) {
     ASSERT(m_pChars);
-    m_pChars->Add(tc);
+    m_pChars->push_back(tc);
     if (m_iWidth < 0) {
       m_iWidth = tc.m_iCharWidth;
     } else {
@@ -97,42 +97,44 @@
     }
     m_iChars++;
   }
+
   int32_t GetEndPos() const {
     return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
   }
+
   int32_t GetLength() const { return m_iChars; }
   int32_t GetEndChar() const { return m_iStartChar + m_iChars; }
+
   CFX_RTFChar& GetChar(int32_t index) {
     ASSERT(index > -1 && index < m_iChars && m_pChars);
-    return *m_pChars->GetDataPtr(m_iStartChar + index);
+    return (*m_pChars)[m_iStartChar + index];
   }
+
   CFX_RTFChar* GetCharPtr(int32_t index) const {
     ASSERT(index > -1 && index < m_iChars && m_pChars);
-    return m_pChars->GetDataPtr(m_iStartChar + index);
+    return &(*m_pChars)[m_iStartChar + index];
   }
+
   void GetString(FX_WCHAR* pText) const {
     ASSERT(pText);
     int32_t iEndChar = m_iStartChar + m_iChars;
-    CFX_RTFChar* pChar;
-    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
-      pChar = m_pChars->GetDataPtr(i);
-      *pText++ = (FX_WCHAR)pChar->m_wCharCode;
-    }
+    for (int32_t i = m_iStartChar; i < iEndChar; i++)
+      *pText++ = static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode);
   }
+
   void GetString(CFX_WideString& wsText) const {
     FX_WCHAR* pText = wsText.GetBuffer(m_iChars);
     GetString(pText);
     wsText.ReleaseBuffer(m_iChars);
   }
+
   void GetWidths(int32_t* pWidths) const {
     ASSERT(pWidths);
     int32_t iEndChar = m_iStartChar + m_iChars;
-    CFX_RTFChar* pChar;
-    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
-      pChar = m_pChars->GetDataPtr(i);
-      *pWidths++ = pChar->m_iCharWidth;
-    }
+    for (int32_t i = m_iStartChar; i < iEndChar; i++)
+      *pWidths++ = (*m_pChars)[i].m_iCharWidth;
   }
+
   void Reset() {
     m_dwStatus = FX_RTFBREAK_PieceBreak;
     if (m_iWidth > -1) {
@@ -160,7 +162,7 @@
   int32_t m_iVerticalScale;
   uint32_t m_dwLayoutStyles;
   uint32_t m_dwIdentity;
-  CFX_RTFCharArray* m_pChars;
+  std::vector<CFX_RTFChar>* m_pChars;  // not owned.
   IFX_Retainable* m_pUserData;
 };
 
@@ -171,14 +173,16 @@
   CFX_RTFLine();
   ~CFX_RTFLine();
 
-  int32_t CountChars() const { return m_LineChars.GetSize(); }
+  int32_t CountChars() const {
+    return pdfium::CollectionSize<int32_t>(m_LineChars);
+  }
   CFX_RTFChar& GetChar(int32_t index) {
-    ASSERT(index > -1 && index < m_LineChars.GetSize());
-    return *m_LineChars.GetDataPtr(index);
+    ASSERT(index >= 0 && index < pdfium::CollectionSize<int32_t>(m_LineChars));
+    return m_LineChars[index];
   }
   CFX_RTFChar* GetCharPtr(int32_t index) {
-    ASSERT(index > -1 && index < m_LineChars.GetSize());
-    return m_LineChars.GetDataPtr(index);
+    ASSERT(index > -1 && index < pdfium::CollectionSize<int32_t>(m_LineChars));
+    return &m_LineChars[index];
   }
   int32_t CountPieces() const { return m_LinePieces.GetSize(); }
   CFX_RTFPiece& GetPiece(int32_t index) const {
@@ -191,21 +195,20 @@
   }
   int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
   void RemoveAll(bool bLeaveMemory = false) {
-    CFX_RTFChar* pChar;
-    int32_t iCount = m_LineChars.GetSize();
+    int32_t iCount = pdfium::CollectionSize<int32_t>(m_LineChars);
     for (int32_t i = 0; i < iCount; i++) {
-      pChar = m_LineChars.GetDataPtr(i);
+      CFX_RTFChar* pChar = &m_LineChars[i];
       if (pChar->m_pUserData)
         pChar->m_pUserData->Release();
     }
-    m_LineChars.RemoveAll();
+    m_LineChars.clear();
     m_LinePieces.RemoveAll(bLeaveMemory);
     m_iWidth = 0;
     m_iArabicChars = 0;
     m_iMBCSChars = 0;
   }
 
-  CFX_RTFCharArray m_LineChars;
+  std::vector<CFX_RTFChar> m_LineChars;
   CFX_RTFPieceArray m_LinePieces;
   int32_t m_iStart;
   int32_t m_iWidth;
@@ -271,7 +274,7 @@
   int32_t GetLastPositionedTab() const;
   bool GetPositionedTab(int32_t& iTabPos) const;
 
-  int32_t GetBreakPos(CFX_RTFCharArray& tca,
+  int32_t GetBreakPos(std::vector<CFX_RTFChar>& tca,
                       int32_t& iEndPos,
                       bool bAllChars = false,
                       bool bOnlyBrk = false);
diff --git a/xfa/fgas/layout/fgas_textbreak.cpp b/xfa/fgas/layout/fgas_textbreak.cpp
index 50e3b06..74f8cb4 100644
--- a/xfa/fgas/layout/fgas_textbreak.cpp
+++ b/xfa/fgas/layout/fgas_textbreak.cpp
@@ -278,15 +278,14 @@
 }
 
 CFX_TxtChar* CFX_TxtBreak::GetLastChar(int32_t index, bool bOmitChar) const {
-  CFX_TxtCharArray& ca = *m_pCurLine->m_pLineChars.get();
-  int32_t iCount = ca.GetSize();
+  std::vector<CFX_TxtChar>& ca = *m_pCurLine->m_pLineChars.get();
+  int32_t iCount = pdfium::CollectionSize<int32_t>(ca);
   if (index < 0 || index >= iCount) {
     return nullptr;
   }
-  CFX_TxtChar* pTC;
   int32_t iStart = iCount - 1;
   while (iStart > -1) {
-    pTC = ca.GetDataPtr(iStart--);
+    CFX_TxtChar* pTC = &ca[iStart--];
     if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) {
       continue;
     }
@@ -595,7 +594,8 @@
 uint32_t CFX_TxtBreak::AppendChar(FX_WCHAR wch) {
   uint32_t dwProps = kTextLayoutCodeProperties[(uint16_t)wch];
   FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps);
-  CFX_TxtChar* pCurChar = m_pCurLine->m_pLineChars->AddSpace();
+  m_pCurLine->m_pLineChars->emplace_back();
+  CFX_TxtChar* pCurChar = &m_pCurLine->m_pLineChars->back();
   pCurChar->m_wCharCode = (uint16_t)wch;
   pCurChar->m_nRotation = m_iCharRotation;
   pCurChar->m_dwCharProps = dwProps;
@@ -619,7 +619,7 @@
         dwRet1 = EndBreak(FX_TXTBREAK_LineBreak);
         int32_t iCount = m_pCurLine->CountChars();
         if (iCount > 0) {
-          pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1);
+          pCurChar = &(*m_pCurLine->m_pLineChars)[iCount - 1];
         }
       }
     }
@@ -744,13 +744,13 @@
   FX_TPO tpo;
   CFX_TxtChar* pTC;
   int32_t i, j;
-  CFX_TxtCharArray& chars = *m_pCurLine->m_pLineChars.get();
+  std::vector<CFX_TxtChar>& chars = *m_pCurLine->m_pLineChars.get();
   int32_t iCount = m_pCurLine->CountChars();
   bool bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL);
   if (!m_bPagination && bDone) {
     int32_t iBidiNum = 0;
     for (i = 0; i < iCount; i++) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       pTC->m_iBidiPos = i;
       if (pTC->GetCharType() != FX_CHARTYPE_Control) {
         iBidiNum = i;
@@ -770,7 +770,7 @@
     int32_t iBidiLevel = -1, iCharWidth;
     i = 0, j = -1;
     while (i < iCount) {
-      pTC = chars.GetDataPtr(i);
+      pTC = &chars[i];
       if (iBidiLevel < 0) {
         iBidiLevel = pTC->m_iBidiLevel;
         tp.m_iWidth = 0;
@@ -837,7 +837,7 @@
     tp.m_iChars = iCount;
     tp.m_pChars = m_pCurLine->m_pLineChars.get();
     tp.m_pUserData = m_pUserData;
-    pTC = chars.GetDataPtr(0);
+    pTC = &chars[0];
     tp.m_dwCharStyles = pTC->m_dwCharStyles;
     tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
     tp.m_iVerticalScale = pTC->m_iVertialScale;
@@ -1006,11 +1006,11 @@
   return dwStatus;
 }
 
-int32_t CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray& ca,
+int32_t CFX_TxtBreak::GetBreakPos(std::vector<CFX_TxtChar>& ca,
                                   int32_t& iEndPos,
                                   bool bAllChars,
                                   bool bOnlyBrk) {
-  int32_t iLength = ca.GetSize() - 1;
+  int32_t iLength = pdfium::CollectionSize<int32_t>(ca) - 1;
   if (iLength < 1) {
     return iLength;
   }
@@ -1027,7 +1027,7 @@
   bool bNumberBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_NumberBreak) != 0;
   FX_LINEBREAKTYPE eType;
   uint32_t nCodeProp, nCur, nNext;
-  CFX_Char* pCur = ca.GetDataPtr(iLength--);
+  CFX_Char* pCur = &ca[iLength--];
   if (bAllChars) {
     pCur->m_nBreakType = FX_LBT_UNKNOWN;
   }
@@ -1038,7 +1038,7 @@
     iEndPos -= iCharWidth;
   }
   while (iLength >= 0) {
-    pCur = ca.GetDataPtr(iLength);
+    pCur = &ca[iLength];
     nCodeProp = pCur->m_dwCharProps;
     nCur = nCodeProp & 0x003F;
     if (nCur == FX_CBP_SP) {
@@ -1112,7 +1112,7 @@
     return;
   }
   int32_t iEndPos = pCurLine->m_iWidth;
-  CFX_TxtCharArray& curChars = *pCurLine->m_pLineChars.get();
+  std::vector<CFX_TxtChar>& curChars = *pCurLine->m_pLineChars;
   int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, false);
   if (iCharPos < 0) {
     iCharPos = 0;
@@ -1120,36 +1120,30 @@
   iCharPos++;
   if (iCharPos >= iCount) {
     pNextLine->RemoveAll(true);
-    CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
+    CFX_Char* pTC = &curChars[iCharPos - 1];
     pTC->m_nBreakType = FX_LBT_UNKNOWN;
     return;
   }
-  CFX_TxtCharArray& nextChars = *pNextLine->m_pLineChars.get();
-  int cur_size = curChars.GetSize();
-  nextChars.SetSize(cur_size - iCharPos);
-  FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
-               (cur_size - iCharPos) * sizeof(CFX_TxtChar));
-  iCount -= iCharPos;
-  cur_size = curChars.GetSize();
-  curChars.RemoveAt(cur_size - iCount, iCount);
+  std::vector<CFX_TxtChar>& nextChars = *pNextLine->m_pLineChars;
+  nextChars =
+      std::vector<CFX_TxtChar>(curChars.begin() + iCharPos, curChars.end());
+  curChars.erase(curChars.begin() + iCharPos, curChars.end());
   pCurLine->m_iWidth = iEndPos;
-  CFX_TxtChar* pTC = curChars.GetDataPtr(iCharPos - 1);
+  CFX_TxtChar* pTC = &curChars[iCharPos - 1];
   pTC->m_nBreakType = FX_LBT_UNKNOWN;
-  iCount = nextChars.GetSize();
-  int32_t iCharWidth, iWidth = 0;
+  iCount = pdfium::CollectionSize<int>(nextChars);
+  int32_t iWidth = 0;
   for (int32_t i = 0; i < iCount; i++) {
-    pTC = nextChars.GetDataPtr(i);
+    pTC = &nextChars[i];
     if (pTC->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
       pCurLine->m_iArabicChars--;
       pNextLine->m_iArabicChars++;
     }
-    iCharWidth = pTC->m_iCharWidth;
-    if (iCharWidth > 0) {
+    int32_t iCharWidth = pTC->m_iCharWidth;
+    if (iCharWidth > 0)
       iWidth += iCharWidth;
-    }
-    if (m_bPagination) {
+    if (m_bPagination)
       continue;
-    }
     pTC->m_dwStatus = 0;
   }
   pNextLine->m_iWidth = iWidth;
@@ -1732,7 +1726,7 @@
       m_pUserData(nullptr) {}
 
 CFX_TxtLine::CFX_TxtLine(int32_t iBlockSize)
-    : m_pLineChars(new CFX_TxtCharArray),
+    : m_pLineChars(new std::vector<CFX_TxtChar>),
       m_pLinePieces(new CFX_TxtPieceArray(16)),
       m_iStart(0),
       m_iWidth(0),
diff --git a/xfa/fgas/layout/fgas_textbreak.h b/xfa/fgas/layout/fgas_textbreak.h
index ea86079..19f1050 100644
--- a/xfa/fgas/layout/fgas_textbreak.h
+++ b/xfa/fgas/layout/fgas_textbreak.h
@@ -12,6 +12,7 @@
 
 #include "core/fxcrt/fx_ucd.h"
 #include "core/fxge/cfx_renderdevice.h"
+#include "third_party/base/stl_util.h"
 #include "xfa/fgas/crt/fgas_utils.h"
 #include "xfa/fgas/layout/fgas_unicode.h"
 
@@ -117,16 +118,13 @@
   int32_t GetEndChar() const { return m_iStartChar + m_iChars; }
   CFX_TxtChar* GetCharPtr(int32_t index) const {
     ASSERT(index > -1 && index < m_iChars && m_pChars);
-    return m_pChars->GetDataPtr(m_iStartChar + index);
+    return &(*m_pChars)[m_iStartChar + index];
   }
   void GetString(FX_WCHAR* pText) const {
     ASSERT(pText);
     int32_t iEndChar = m_iStartChar + m_iChars;
-    CFX_Char* pChar;
-    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
-      pChar = m_pChars->GetDataPtr(i);
-      *pText++ = (FX_WCHAR)pChar->m_wCharCode;
-    }
+    for (int32_t i = m_iStartChar; i < iEndChar; i++)
+      *pText++ = static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode);
   }
   void GetString(CFX_WideString& wsText) const {
     FX_WCHAR* pText = wsText.GetBuffer(m_iChars);
@@ -136,11 +134,8 @@
   void GetWidths(int32_t* pWidths) const {
     ASSERT(pWidths);
     int32_t iEndChar = m_iStartChar + m_iChars;
-    CFX_Char* pChar;
-    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
-      pChar = m_pChars->GetDataPtr(i);
-      *pWidths++ = pChar->m_iCharWidth;
-    }
+    for (int32_t i = m_iStartChar; i < iEndChar; i++)
+      *pWidths++ = (*m_pChars)[i].m_iCharWidth;
   }
 
   uint32_t m_dwStatus;
@@ -153,7 +148,7 @@
   int32_t m_iHorizontalScale;
   int32_t m_iVerticalScale;
   uint32_t m_dwCharStyles;
-  CFX_TxtCharArray* m_pChars;
+  std::vector<CFX_TxtChar>* m_pChars;
   void* m_pUserData;
 };
 
@@ -164,34 +159,38 @@
   explicit CFX_TxtLine(int32_t iBlockSize);
   ~CFX_TxtLine();
 
-  int32_t CountChars() const { return m_pLineChars->GetSize(); }
-  CFX_TxtChar* GetCharPtr(int32_t index) const {
-    ASSERT(index > -1 && index < m_pLineChars->GetSize());
-    return m_pLineChars->GetDataPtr(index);
+  int32_t CountChars() const {
+    return pdfium::CollectionSize<int32_t>(*m_pLineChars);
   }
+
+  CFX_TxtChar* GetCharPtr(int32_t index) const {
+    ASSERT(index >= 0 &&
+           index < pdfium::CollectionSize<int32_t>(*m_pLineChars));
+    return &(*m_pLineChars)[index];
+  }
+
   int32_t CountPieces() const { return m_pLinePieces->GetSize(); }
   CFX_TxtPiece* GetPiecePtr(int32_t index) const {
     ASSERT(index > -1 && index < m_pLinePieces->GetSize());
     return m_pLinePieces->GetPtrAt(index);
   }
+
   void GetString(CFX_WideString& wsStr) const {
-    int32_t iCount = m_pLineChars->GetSize();
+    int32_t iCount = pdfium::CollectionSize<int32_t>(*m_pLineChars);
     FX_WCHAR* pBuf = wsStr.GetBuffer(iCount);
-    CFX_Char* pChar;
-    for (int32_t i = 0; i < iCount; i++) {
-      pChar = m_pLineChars->GetDataPtr(i);
-      *pBuf++ = (FX_WCHAR)pChar->m_wCharCode;
-    }
+    for (int32_t i = 0; i < iCount; i++)
+      *pBuf++ = static_cast<FX_WCHAR>((*m_pLineChars)[i].m_wCharCode);
     wsStr.ReleaseBuffer(iCount);
   }
+
   void RemoveAll(bool bLeaveMemory = false) {
-    m_pLineChars->RemoveAll();
+    m_pLineChars->clear();
     m_pLinePieces->RemoveAll(bLeaveMemory);
     m_iWidth = 0;
     m_iArabicChars = 0;
   }
 
-  std::unique_ptr<CFX_TxtCharArray> m_pLineChars;
+  std::unique_ptr<std::vector<CFX_TxtChar>> m_pLineChars;
   std::unique_ptr<CFX_TxtPieceArray> m_pLinePieces;
   int32_t m_iStart;
   int32_t m_iWidth;
@@ -261,7 +260,7 @@
   void EndBreak_Alignment(CFX_TPOArray& tpos,
                           bool bAllChars,
                           uint32_t dwStatus);
-  int32_t GetBreakPos(CFX_TxtCharArray& ca,
+  int32_t GetBreakPos(std::vector<CFX_TxtChar>& ca,
                       int32_t& iEndPos,
                       bool bAllChars = false,
                       bool bOnlyBrk = false);