Use std::vector<TextCharPos> in CXFA_TextLayout.

And in CFX_RTFBreak.

Change-Id: I5bca237e53f90f211bd9c35de60133e84e4fe3c9
Reviewed-on: https://pdfium-review.googlesource.com/c/50113
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fgas/layout/cfx_rtfbreak.cpp b/xfa/fgas/layout/cfx_rtfbreak.cpp
index 5a86528..543f6f3 100644
--- a/xfa/fgas/layout/cfx_rtfbreak.cpp
+++ b/xfa/fgas/layout/cfx_rtfbreak.cpp
@@ -718,7 +718,7 @@
 }
 
 size_t CFX_RTFBreak::GetDisplayPos(const CFX_TextPiece* pPiece,
-                                   TextCharPos* pCharPos) const {
+                                   std::vector<TextCharPos>* pCharPos) const {
   ASSERT(pPiece->iChars > 0);
   ASSERT(pPiece->pFont);
 
@@ -747,6 +747,7 @@
   float fY = rtText.top + fAscent;
   size_t szCount = 0;
   for (int32_t i = 0; i < pPiece->iChars; ++i) {
+    TextCharPos& current_char_pos = (*pCharPos)[szCount];
     wchar_t wch = pPiece->szText[i];
     int32_t iWidth = pPiece->Widths[i];
     FX_CHARTYPE dwCharType = FX_GetCharType(wch);
@@ -757,66 +758,63 @@
     }
 
     uint32_t iCharWidth = abs(iWidth);
-    bool bEmptyChar = (dwCharType >= FX_CHARTYPE::kTab &&
-                       dwCharType <= FX_CHARTYPE::kControl);
+    const bool bEmptyChar = (dwCharType >= FX_CHARTYPE::kTab &&
+                             dwCharType <= FX_CHARTYPE::kControl);
     if (!bEmptyChar)
       ++szCount;
 
-    if (pCharPos) {
-      iCharWidth /= iFontSize;
-      wchar_t wForm = wch;
-      if (dwCharType >= FX_CHARTYPE::kArabicAlef) {
-        if (i + 1 < pPiece->iChars) {
-          wNext = pPiece->szText[i + 1];
-          if (pPiece->Widths[i + 1] < 0 && i + 2 < pPiece->iChars)
-            wNext = pPiece->szText[i + 2];
-        } else {
-          wNext = 0xFEFF;
-        }
-        wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext);
-      } else if (bRTLPiece) {
-        wForm = FX_GetMirrorChar(wch);
+    iCharWidth /= iFontSize;
+    wchar_t wForm = wch;
+    if (dwCharType >= FX_CHARTYPE::kArabicAlef) {
+      if (i + 1 < pPiece->iChars) {
+        wNext = pPiece->szText[i + 1];
+        if (pPiece->Widths[i + 1] < 0 && i + 2 < pPiece->iChars)
+          wNext = pPiece->szText[i + 2];
+      } else {
+        wNext = 0xFEFF;
       }
+      wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext);
+    } else if (bRTLPiece) {
+      wForm = FX_GetMirrorChar(wch);
+    }
 
-      if (!bEmptyChar) {
-        pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm);
-        if (pCharPos->m_GlyphIndex == 0xFFFF)
-          pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch);
+    if (!bEmptyChar) {
+      current_char_pos.m_GlyphIndex = pFont->GetGlyphIndex(wForm);
+      if (current_char_pos.m_GlyphIndex == 0xFFFF)
+        current_char_pos.m_GlyphIndex = pFont->GetGlyphIndex(wch);
 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
-        pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
+      current_char_pos.m_ExtGID = current_char_pos.m_GlyphIndex;
 #endif
-        pCharPos->m_FontCharWidth = iCharWidth;
-      }
+      current_char_pos.m_FontCharWidth = iCharWidth;
+    }
 
-      float fCharWidth = fFontSize * iCharWidth / 1000.0f;
-      if (bRTLPiece && dwCharType != FX_CHARTYPE::kCombination)
-        fX -= fCharWidth;
+    float fCharWidth = fFontSize * iCharWidth / 1000.0f;
+    if (bRTLPiece && dwCharType != FX_CHARTYPE::kCombination)
+      fX -= fCharWidth;
 
-      if (!bEmptyChar)
-        pCharPos->m_Origin = CFX_PointF(fX, fY);
-      if (!bRTLPiece && dwCharType != FX_CHARTYPE::kCombination)
-        fX += fCharWidth;
+    if (!bEmptyChar)
+      current_char_pos.m_Origin = CFX_PointF(fX, fY);
+    if (!bRTLPiece && dwCharType != FX_CHARTYPE::kCombination)
+      fX += fCharWidth;
 
-      if (!bEmptyChar) {
-        pCharPos->m_bGlyphAdjust = true;
-        pCharPos->m_AdjustMatrix[0] = -1;
-        pCharPos->m_AdjustMatrix[1] = 0;
-        pCharPos->m_AdjustMatrix[2] = 0;
-        pCharPos->m_AdjustMatrix[3] = 1;
-        pCharPos->m_Origin.y += fAscent * iVerScale / 100.0f;
-        pCharPos->m_Origin.y -= fAscent;
+    if (!bEmptyChar) {
+      current_char_pos.m_bGlyphAdjust = true;
+      current_char_pos.m_AdjustMatrix[0] = -1;
+      current_char_pos.m_AdjustMatrix[1] = 0;
+      current_char_pos.m_AdjustMatrix[2] = 0;
+      current_char_pos.m_AdjustMatrix[3] = 1;
+      current_char_pos.m_Origin.y += fAscent * iVerScale / 100.0f;
+      current_char_pos.m_Origin.y -= fAscent;
 
-        if (iHorScale != 100 || iVerScale != 100) {
-          pCharPos->m_AdjustMatrix[0] =
-              pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f;
-          pCharPos->m_AdjustMatrix[1] =
-              pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f;
-          pCharPos->m_AdjustMatrix[2] =
-              pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f;
-          pCharPos->m_AdjustMatrix[3] =
-              pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f;
-        }
-        ++pCharPos;
+      if (iHorScale != 100 || iVerScale != 100) {
+        current_char_pos.m_AdjustMatrix[0] =
+            current_char_pos.m_AdjustMatrix[0] * iHorScale / 100.0f;
+        current_char_pos.m_AdjustMatrix[1] =
+            current_char_pos.m_AdjustMatrix[1] * iHorScale / 100.0f;
+        current_char_pos.m_AdjustMatrix[2] =
+            current_char_pos.m_AdjustMatrix[2] * iVerScale / 100.0f;
+        current_char_pos.m_AdjustMatrix[3] =
+            current_char_pos.m_AdjustMatrix[3] * iVerScale / 100.0f;
       }
     }
     if (iWidth > 0)
diff --git a/xfa/fgas/layout/cfx_rtfbreak.h b/xfa/fgas/layout/cfx_rtfbreak.h
index ef24204..dced48e 100644
--- a/xfa/fgas/layout/cfx_rtfbreak.h
+++ b/xfa/fgas/layout/cfx_rtfbreak.h
@@ -43,7 +43,7 @@
   CFX_BreakType EndBreak(CFX_BreakType dwStatus);
 
   size_t GetDisplayPos(const CFX_TextPiece* pPiece,
-                       TextCharPos* pCharPos) const;
+                       std::vector<TextCharPos>* pCharPos) const;
 
   CFX_BreakType AppendChar(wchar_t wch);
 
diff --git a/xfa/fxfa/cxfa_textlayout.cpp b/xfa/fxfa/cxfa_textlayout.cpp
index 4a942bc..1b934c4 100644
--- a/xfa/fxfa/cxfa_textlayout.cpp
+++ b/xfa/fxfa/cxfa_textlayout.cpp
@@ -577,9 +577,7 @@
       LayoutInternal(i);
   }
 
-  TextCharPos* pCharPos = FX_Alloc(TextCharPos, 1);
-  // TODO(thestig): Make this size_t.
-  int32_t iCharCount = 1;
+  std::vector<TextCharPos> char_pos(1);
   size_t szLineStart = 0;
   size_t szPieceLines = m_pieceLines.size();
   if (!m_Blocks.empty()) {
@@ -599,18 +597,14 @@
     for (size_t j = 0; j < pPieceLine->m_textPieces.size(); ++j) {
       const CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[j].get();
       int32_t iChars = pPiece->iChars;
-      if (iCharCount < iChars) {
-        pCharPos = FX_Realloc(TextCharPos, pCharPos, iChars);
-        iCharCount = iChars;
-      }
-      memset(pCharPos, 0, iCharCount * sizeof(TextCharPos));
-      RenderString(pFxDevice, pPieceLine, j, pCharPos, tmDoc2Device);
+      if (pdfium::CollectionSize<int32_t>(char_pos) < iChars)
+        char_pos.resize(iChars);
+      RenderString(pFxDevice, pPieceLine, j, &char_pos, tmDoc2Device);
     }
     for (size_t j = 0; j < pPieceLine->m_textPieces.size(); ++j)
-      RenderPath(pFxDevice, pPieceLine, j, pCharPos, tmDoc2Device);
+      RenderPath(pFxDevice, pPieceLine, j, &char_pos, tmDoc2Device);
   }
   pFxDevice->RestoreState(false);
-  FX_Free(pCharPos);
   return szPieceLines > 0;
 }
 
@@ -1123,14 +1117,14 @@
 void CXFA_TextLayout::RenderString(CFX_RenderDevice* pDevice,
                                    CXFA_PieceLine* pPieceLine,
                                    size_t szPiece,
-                                   TextCharPos* pCharPos,
+                                   std::vector<TextCharPos>* pCharPos,
                                    const CFX_Matrix& tmDoc2Device) {
   const CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[szPiece].get();
   size_t szCount = GetDisplayPos(pPiece, pCharPos);
   if (szCount > 0) {
-    CFDE_TextOut::DrawString(pDevice, pPiece->dwColor, pPiece->pFont,
-                             {pCharPos, szCount}, pPiece->fFontSize,
-                             &tmDoc2Device);
+    auto span = pdfium::make_span(pCharPos->data(), szCount);
+    CFDE_TextOut::DrawString(pDevice, pPiece->dwColor, pPiece->pFont, span,
+                             pPiece->fFontSize, &tmDoc2Device);
   }
   pPieceLine->m_charCounts.push_back(szCount);
 }
@@ -1138,7 +1132,7 @@
 void CXFA_TextLayout::RenderPath(CFX_RenderDevice* pDevice,
                                  CXFA_PieceLine* pPieceLine,
                                  size_t szPiece,
-                                 TextCharPos* pCharPos,
+                                 std::vector<TextCharPos>* pCharPos,
                                  const CFX_Matrix& tmDoc2Device) {
   CXFA_TextPiece* pPiece = pPieceLine->m_textPieces[szPiece].get();
   bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
@@ -1151,33 +1145,34 @@
   if (szChars > 0) {
     CFX_PointF pt1;
     CFX_PointF pt2;
-    float fEndY = pCharPos[0].m_Origin.y + 1.05f;
+    float fEndY = (*pCharPos)[0].m_Origin.y + 1.05f;
     if (pPiece->iPeriod == XFA_AttributeValue::Word) {
       for (int32_t i = 0; i < pPiece->iUnderline; i++) {
         for (size_t j = 0; j < szChars; j++) {
-          pt1.x = pCharPos[j].m_Origin.x;
-          pt2.x =
-              pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+          pt1.x = (*pCharPos)[j].m_Origin.x;
+          pt2.x = pt1.x +
+                  (*pCharPos)[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
           pt1.y = pt2.y = fEndY;
           path.AppendLine(pt1, pt2);
         }
         fEndY += 2.0f;
       }
     } else {
-      pt1.x = pCharPos[0].m_Origin.x;
-      pt2.x =
-          pCharPos[szChars - 1].m_Origin.x +
-          pCharPos[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+      pt1.x = (*pCharPos)[0].m_Origin.x;
+      pt2.x = (*pCharPos)[szChars - 1].m_Origin.x +
+              (*pCharPos)[szChars - 1].m_FontCharWidth * pPiece->fFontSize /
+                  1000.0f;
       for (int32_t i = 0; i < pPiece->iUnderline; i++) {
         pt1.y = pt2.y = fEndY;
         path.AppendLine(pt1, pt2);
         fEndY += 2.0f;
       }
     }
-    fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f;
-    pt1.x = pCharPos[0].m_Origin.x;
-    pt2.x = pCharPos[szChars - 1].m_Origin.x +
-            pCharPos[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+    fEndY = (*pCharPos)[0].m_Origin.y - pPiece->rtPiece.height * 0.25f;
+    pt1.x = (*pCharPos)[0].m_Origin.x;
+    pt2.x =
+        (*pCharPos)[szChars - 1].m_Origin.x +
+        (*pCharPos)[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
     for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
       pt1.y = pt2.y = fEndY;
       path.AppendLine(pt1, pt2);
@@ -1219,26 +1214,27 @@
     if (szChars < 1)
       return;
 
-    fOrgX = pCharPos[szChars - 1].m_Origin.x +
-            pCharPos[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+    fOrgX =
+        (*pCharPos)[szChars - 1].m_Origin.x +
+        (*pCharPos)[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
     pPiece = pPieceLine->m_textPieces[szPieceNext].get();
     szChars = GetDisplayPos(pPiece, pCharPos);
     if (szChars < 1)
       return;
 
-    fEndX = pCharPos[0].m_Origin.x;
+    fEndX = (*pCharPos)[0].m_Origin.x;
     CFX_PointF pt1;
     CFX_PointF pt2;
     pt1.x = fOrgX;
     pt2.x = fEndX;
-    float fEndY = pCharPos[0].m_Origin.y + 1.05f;
+    float fEndY = (*pCharPos)[0].m_Origin.y + 1.05f;
     for (int32_t i = 0; i < pPiece->iUnderline; i++) {
       pt1.y = fEndY;
       pt2.y = fEndY;
       path.AppendLine(pt1, pt2);
       fEndY += 2.0f;
     }
-    fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f;
+    fEndY = (*pCharPos)[0].m_Origin.y - pPiece->rtPiece.height * 0.25f;
     for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
       pt1.y = fEndY;
       pt2.y = fEndY;
@@ -1257,7 +1253,7 @@
 }
 
 size_t CXFA_TextLayout::GetDisplayPos(const CXFA_TextPiece* pPiece,
-                                      TextCharPos* pCharPos) {
+                                      std::vector<TextCharPos>* pCharPos) {
   if (!pPiece || pPiece->iChars < 1)
     return 0;
   return m_pBreak->GetDisplayPos(pPiece, pCharPos);
diff --git a/xfa/fxfa/cxfa_textlayout.h b/xfa/fxfa/cxfa_textlayout.h
index 847c98e..4d739d6 100644
--- a/xfa/fxfa/cxfa_textlayout.h
+++ b/xfa/fxfa/cxfa_textlayout.h
@@ -104,14 +104,15 @@
   void RenderString(CFX_RenderDevice* pDevice,
                     CXFA_PieceLine* pPieceLine,
                     size_t szPiece,
-                    TextCharPos* pCharPos,
+                    std::vector<TextCharPos>* pCharPos,
                     const CFX_Matrix& tmDoc2Device);
   void RenderPath(CFX_RenderDevice* pDevice,
                   CXFA_PieceLine* pPieceLine,
                   size_t szPiece,
-                  TextCharPos* pCharPos,
+                  std::vector<TextCharPos>* pCharPos,
                   const CFX_Matrix& tmDoc2Device);
-  size_t GetDisplayPos(const CXFA_TextPiece* pPiece, TextCharPos* pCharPos);
+  size_t GetDisplayPos(const CXFA_TextPiece* pPiece,
+                       std::vector<TextCharPos>* pCharPos);
   void DoTabstops(CFX_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
   bool LayoutInternal(size_t szBlockIndex);
   size_t CountBlocks() const;