Merge to XFA: CFX_MapByteStringToPtr considered harmful (combo patch).

New manual edits: two unused members deleted, one adapted.
    fde_csscache.cpp
    fde_csscache.h
    fpdfxfa_doc.h
    fx_ge_fontmap.cpp

(cherry picked from commit 1d9dbd53b205b2b4d9e75a7eeb95e80837917ea3)
(cherry picked from commit cb4d0ea68308e3c51a6ba9551b393bb2f639afc4)
(cherry picked from commit 9cf44c2ed09a8b2ff243eb6dbb72a8cceae1b5ff)
(cherry picked from commit 2a2a6aa7f51352fc481e78f6ad9d41f2738bcc48)
(cherry picked from commit ce4ffb8183af3fa2bb5133f0f7370a88e064c516)
Original Review URL: https://codereview.chromium.org/1297723002 .

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1301793002 .
diff --git a/core/include/fxcrt/fx_basic.h b/core/include/fxcrt/fx_basic.h
index 54c78ea..71c664c 100644
--- a/core/include/fxcrt/fx_basic.h
+++ b/core/include/fxcrt/fx_basic.h
@@ -757,75 +757,6 @@
  protected:
   CFX_BinaryBuf m_Buffer;
 };
-class CFX_MapByteStringToPtr {
- protected:
-  struct CAssoc {
-    CAssoc* pNext;
-
-    FX_DWORD nHashValue;
-
-    CFX_ByteString key;
-
-    void* value;
-  };
-
- public:
-  CFX_MapByteStringToPtr(int nBlockSize = 10);
-
-  int GetCount() const { return m_nCount; }
-
-  FX_BOOL IsEmpty() const { return m_nCount == 0; }
-
-  FX_BOOL Lookup(const CFX_ByteStringC& key, void*& rValue) const;
-
-  void*& operator[](const CFX_ByteStringC& key);
-
-  void SetAt(const CFX_ByteStringC& key, void* newValue) {
-    (*this)[key] = newValue;
-  }
-
-  FX_BOOL RemoveKey(const CFX_ByteStringC& key);
-
-  void RemoveAll();
-
-  FX_POSITION GetStartPosition() const {
-    return (m_nCount == 0) ? NULL : (FX_POSITION)-1;
-  }
-
-  void GetNextAssoc(FX_POSITION& rNextPosition,
-                    CFX_ByteString& rKey,
-                    void*& rValue) const;
-
-  void* GetNextValue(FX_POSITION& rNextPosition) const;
-
-  FX_DWORD GetHashTableSize() const { return m_nHashTableSize; }
-
-  void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE);
-
-  FX_DWORD HashKey(const CFX_ByteStringC& key) const;
-
- protected:
-  CAssoc** m_pHashTable;
-
-  FX_DWORD m_nHashTableSize;
-
-  int m_nCount;
-
-  CAssoc* m_pFreeList;
-
-  struct CFX_Plex* m_pBlocks;
-
-  int m_nBlockSize;
-
-  CAssoc* NewAssoc();
-
-  void FreeAssoc(CAssoc* pAssoc);
-
-  CAssoc* GetAssocAt(const CFX_ByteStringC& key, FX_DWORD& hash) const;
-
- public:
-  ~CFX_MapByteStringToPtr();
-};
 class CFX_CMapByteStringToPtr {
  public:
   CFX_CMapByteStringToPtr();
diff --git a/core/include/fxge/fx_font.h b/core/include/fxge/fx_font.h
index 7eaa323..30de472 100644
--- a/core/include/fxge/fx_font.h
+++ b/core/include/fxge/fx_font.h
@@ -14,11 +14,16 @@
 
 typedef struct FT_FaceRec_* FXFT_Face;
 typedef void* FXFT_Library;
-class CFontFileFaceInfo;
+
 class CFX_FaceCache;
+class CFX_FontFaceInfo;
 class CFX_FontMapper;
 class CFX_PathData;
+class CFX_SizeGlyphCache;
 class CFX_SubstFont;
+class CFontFileFaceInfo;
+class CTTFontDesc;
+class IFX_FontEncoding;
 class IFX_SystemFontInfo;
 
 #define FXFONT_FIXED_PITCH 0x01
@@ -263,12 +268,11 @@
                           int italic_angle,
                           int CharsetCP,
                           CFX_SubstFont* pSubstFont);
-
   void FreeCache();
-
   FX_BOOL GetStandardFont(const uint8_t*& pFontData, FX_DWORD& size, int index);
+
   CFX_FontMapper* m_pBuiltinMapper;
-  CFX_MapByteStringToPtr m_FaceMap;
+  std::map<CFX_ByteString, CTTFontDesc*> m_FaceMap;
   FXFT_Library m_FTLibrary;
   FoxitFonts m_ExternalFonts[16];
 };
@@ -406,7 +410,7 @@
   FX_BOOL GetFontCharset(void* hFont, int& charset) override;
 
  protected:
-  CFX_MapByteStringToPtr m_FontList;
+  std::map<CFX_ByteString, CFX_FontFaceInfo*> m_FontList;
   CFX_ByteStringArray m_PathList;
   CFX_FontMapper* m_pMapper;
   void ScanPath(CFX_ByteString& path);
@@ -486,7 +490,7 @@
                                      FX_BOOL bFontStyle,
                                      int dest_width,
                                      int anti_alias);
-  CFX_MapByteStringToPtr m_SizeMap;
+  std::map<CFX_ByteString, CFX_SizeGlyphCache*> m_SizeMap;
   CFX_MapPtrToPtr m_PathMap;
   CFX_DIBitmap* m_pBitmap;
 
diff --git a/core/src/fpdfapi/fpdf_font/font_int.h b/core/src/fpdfapi/fpdf_font/font_int.h
index d7cbe1b..30223ad 100644
--- a/core/src/fpdfapi/fpdf_font/font_int.h
+++ b/core/src/fpdfapi/fpdf_font/font_int.h
@@ -3,10 +3,22 @@
 // found in the LICENSE file.
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
 #ifndef CORE_SRC_FPDFAPI_FPDF_FONT_FONT_INT_H_
 #define CORE_SRC_FPDFAPI_FPDF_FONT_FONT_INT_H_
 
+#include <map>
+
+#include "../../../include/fxcrt/fx_basic.h"
+#include "../../../include/fpdfapi/fpdf_resource.h"
+
+class CPDF_CID2UnicodeMap;
+class CPDF_CMap;
+class CPDF_Font;
+class CPDF_Stream;
+
 typedef void* FXFT_Library;
+
 class CPDF_CMapManager {
  public:
   CPDF_CMapManager();
@@ -19,9 +31,9 @@
  private:
   CPDF_CMap* LoadPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPrompt);
   CPDF_CID2UnicodeMap* LoadCID2UnicodeMap(int charset, FX_BOOL bPrompt);
-  void DropAll(FX_BOOL bReload);
+
   FX_BOOL m_bPrompted;
-  CFX_MapByteStringToPtr m_CMaps;
+  std::map<CFX_ByteString, CPDF_CMap*> m_CMaps;
   CPDF_CID2UnicodeMap* m_CID2UnicodeMaps[6];
 };
 class CPDF_FontGlobals {
diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
index 6c72824..ebb99fa 100644
--- a/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
+++ b/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
@@ -22,19 +22,24 @@
   FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps);
 }
 CPDF_CMapManager::~CPDF_CMapManager() {
-  DropAll(FALSE);
+  for (const auto& pair : m_CMaps) {
+    delete pair.second;
+  }
+  m_CMaps.clear();
+  for (int i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
+    delete m_CID2UnicodeMaps[i];
+  }
 }
 CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name,
                                                FX_BOOL bPromptCJK) {
-  CPDF_CMap* pCMap;
-  if (m_CMaps.Lookup(name, (void*&)pCMap)) {
-    return pCMap;
+  auto it = m_CMaps.find(name);
+  if (it != m_CMaps.end()) {
+    return it->second;
   }
-  pCMap = LoadPredefinedCMap(name, bPromptCJK);
-  if (name.IsEmpty()) {
-    return pCMap;
+  CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK);
+  if (!name.IsEmpty()) {
+    m_CMaps[name] = pCMap;
   }
-  m_CMaps.SetAt(name, pCMap);
   return pCMap;
 }
 CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name,
@@ -59,33 +64,13 @@
   return CIDSET_UNKNOWN;
 }
 void CPDF_CMapManager::ReloadAll() {
-  DropAll(TRUE);
-}
-void CPDF_CMapManager::DropAll(FX_BOOL bReload) {
-  FX_POSITION pos = m_CMaps.GetStartPosition();
-  while (pos) {
-    CFX_ByteString name;
-    CPDF_CMap* pCMap;
-    m_CMaps.GetNextAssoc(pos, name, (void*&)pCMap);
-    if (pCMap == NULL) {
-      continue;
-    }
-    if (bReload) {
-      pCMap->LoadPredefined(this, name, FALSE);
-    } else {
-      delete pCMap;
-    }
+  for (const auto& pair : m_CMaps) {
+    CPDF_CMap* pCMap = pair.second;
+    pCMap->LoadPredefined(this, pair.first, FALSE);
   }
-  for (int i = 0; i < sizeof m_CID2UnicodeMaps / sizeof(CPDF_CID2UnicodeMap*);
-       i++) {
-    CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i];
-    if (pMap == NULL) {
-      continue;
-    }
-    if (bReload) {
+  for (int i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
+    if (CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i]) {
       pMap->Load(this, i, FALSE);
-    } else {
-      delete pMap;
     }
   }
 }
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
index 74e33b5..210d543 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
@@ -171,14 +171,10 @@
       continue;
 
     if (bForceRelease || ipData->use_count() < 2) {
-      CPDF_Stream* ipKey = curr_it->first;
-      FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
-      while (pos2) {
-        CFX_ByteString bsKey;
-        CPDF_Stream* pFindStream = nullptr;
-        m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream);
-        if (ipKey == pFindStream) {
-          m_HashProfileMap.RemoveKey(bsKey);
+      for (auto hash_it = m_HashProfileMap.begin();
+           hash_it != m_HashProfileMap.end(); ++hash_it) {
+        if (curr_it->first == hash_it->second) {
+          m_HashProfileMap.erase(hash_it);
           break;
         }
       }
@@ -519,18 +515,17 @@
   CPDF_StreamAcc stream;
   stream.LoadAllData(pIccProfileStream, FALSE);
   uint8_t digest[20];
-  CPDF_Stream* pCopiedStream = nullptr;
   CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest);
-  if (m_HashProfileMap.Lookup(CFX_ByteStringC(digest, 20),
-                              (void*&)pCopiedStream)) {
-    auto it_copied_stream = m_IccProfileMap.find(pCopiedStream);
+  auto hash_it = m_HashProfileMap.find(CFX_ByteStringC(digest, 20));
+  if (hash_it != m_HashProfileMap.end()) {
+    auto it_copied_stream = m_IccProfileMap.find(hash_it->second);
     return it_copied_stream->second->AddRef();
   }
   CPDF_IccProfile* pProfile =
       new CPDF_IccProfile(stream.GetData(), stream.GetSize());
   CPDF_CountedIccProfile* ipData = new CPDF_CountedIccProfile(pProfile);
   m_IccProfileMap[pIccProfileStream] = ipData;
-  m_HashProfileMap.SetAt(CFX_ByteStringC(digest, 20), pIccProfileStream);
+  m_HashProfileMap[CFX_ByteStringC(digest, 20)] = pIccProfileStream;
   return ipData->AddRef();
 }
 
diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h
index c931af7..4f60cf5 100644
--- a/core/src/fpdfapi/fpdf_page/pageint.h
+++ b/core/src/fpdfapi/fpdf_page/pageint.h
@@ -423,9 +423,8 @@
   using CPDF_PatternMap = std::map<CPDF_Object*, CPDF_CountedPattern*>;
 
   CPDF_Document* const m_pPDFDoc;
-  CFX_MapByteStringToPtr m_HashProfileMap;
   FX_BOOL m_bForceClear;
-
+  std::map<CFX_ByteString, CPDF_Stream*> m_HashProfileMap;
   CPDF_ColorSpaceMap m_ColorSpaceMap;
   CPDF_FontFileMap m_FontFileMap;
   CPDF_FontMap m_FontMap;
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
index d36125e..5038833 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp
@@ -11,14 +11,10 @@
 #include "render_int.h"
 extern FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix);
 CPDF_Type3Cache::~CPDF_Type3Cache() {
-  FX_POSITION pos = m_SizeMap.GetStartPosition();
-  CFX_ByteString Key;
-  CPDF_Type3Glyphs* pSizeCache = NULL;
-  while (pos) {
-    pSizeCache = (CPDF_Type3Glyphs*)m_SizeMap.GetNextValue(pos);
-    delete pSizeCache;
+  for (const auto& pair : m_SizeMap) {
+    delete pair.second;
   }
-  m_SizeMap.RemoveAll();
+  m_SizeMap.clear();
 }
 CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode,
                                             const CFX_AffineMatrix* pMatrix,
@@ -29,10 +25,13 @@
       4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000),
       FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000));
   CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
-  CPDF_Type3Glyphs* pSizeCache = NULL;
-  if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
+  CPDF_Type3Glyphs* pSizeCache;
+  auto it = m_SizeMap.find(FaceGlyphsKey);
+  if (it == m_SizeMap.end()) {
     pSizeCache = new CPDF_Type3Glyphs;
-    m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
+    m_SizeMap[FaceGlyphsKey] = pSizeCache;
+  } else {
+    pSizeCache = it->second;
   }
   CFX_GlyphBitmap* pGlyphBitmap;
   if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)charcode,
diff --git a/core/src/fpdfapi/fpdf_render/render_int.h b/core/src/fpdfapi/fpdf_render/render_int.h
index 733e24c..e195472 100644
--- a/core/src/fpdfapi/fpdf_render/render_int.h
+++ b/core/src/fpdfapi/fpdf_render/render_int.h
@@ -12,8 +12,11 @@
 #include "../../../../third_party/base/nonstd_unique_ptr.h"
 #include "../../../include/fpdfapi/fpdf_pageobj.h"
 
+class CFX_GlyphBitmap;
 class CPDF_QuickStretcher;
+
 #define TYPE3_MAX_BLUES 16
+
 class CPDF_Type3Glyphs {
  public:
   CPDF_Type3Glyphs() {
@@ -30,11 +33,11 @@
   int m_TopBlue[TYPE3_MAX_BLUES], m_BottomBlue[TYPE3_MAX_BLUES];
   int m_TopBlueCount, m_BottomBlueCount;
 };
-class CFX_GlyphBitmap;
 class CPDF_Type3Cache {
  public:
-  CPDF_Type3Cache(CPDF_Type3Font* pFont) { m_pFont = pFont; }
+  explicit CPDF_Type3Cache(CPDF_Type3Font* pFont) : m_pFont(pFont) {}
   ~CPDF_Type3Cache();
+
   CFX_GlyphBitmap* LoadGlyph(FX_DWORD charcode,
                              const CFX_AffineMatrix* pMatrix,
                              FX_FLOAT retinaScaleX = 1.0f,
@@ -46,8 +49,8 @@
                                const CFX_AffineMatrix* pMatrix,
                                FX_FLOAT retinaScaleX = 1.0f,
                                FX_FLOAT retinaScaleY = 1.0f);
-  CPDF_Type3Font* m_pFont;
-  CFX_MapByteStringToPtr m_SizeMap;
+  CPDF_Type3Font* const m_pFont;
+  std::map<CFX_ByteString, CPDF_Type3Glyphs*> m_SizeMap;
 };
 class CPDF_TransferFunc {
  public:
diff --git a/core/src/fxcodec/codec/codec_int.h b/core/src/fxcodec/codec/codec_int.h
index ae6af00..d172d71 100644
--- a/core/src/fxcodec/codec/codec_int.h
+++ b/core/src/fxcodec/codec/codec_int.h
@@ -9,11 +9,15 @@
 
 #include <limits.h>
 #include <list>
+#include <map>
 
 #include "../../../../third_party/libopenjpeg20/openjpeg.h"  // For OPJ_SIZE_T.
 #include "../../../include/fxcodec/fx_codec.h"
 #include "../jbig2/JBig2_Context.h"
 
+class CFX_IccProfileCache;
+class CFX_IccTransformCache;
+
 class CCodec_BasicModule : public ICodec_BasicModule {
  public:
   virtual FX_BOOL RunLengthEncode(const uint8_t* src_buf,
@@ -289,18 +293,19 @@
   virtual ~CCodec_IccModule();
 
  protected:
-  CFX_MapByteStringToPtr m_MapTranform;
-  CFX_MapByteStringToPtr m_MapProfile;
-  FX_DWORD m_nComponents;
-  typedef enum {
+  enum Icc_CLASS {
     Icc_CLASS_INPUT = 0,
     Icc_CLASS_OUTPUT,
     Icc_CLASS_PROOF,
     Icc_CLASS_MAX
-  } Icc_CLASS;
+  };
   void* CreateProfile(ICodec_IccModule::IccParam* pIccParam,
                       Icc_CLASS ic,
                       CFX_BinaryBuf* pTransformKey);
+
+  FX_DWORD m_nComponents;
+  std::map<CFX_ByteString, CFX_IccTransformCache*> m_MapTranform;
+  std::map<CFX_ByteString, CFX_IccProfileCache*> m_MapProfile;
 };
 
 class CCodec_JpxModule : public ICodec_JpxModule {
diff --git a/core/src/fxcodec/codec/fx_codec_icc.cpp b/core/src/fxcodec/codec/fx_codec_icc.cpp
index dad880a..2a8ccc3 100644
--- a/core/src/fxcodec/codec/fx_codec_icc.cpp
+++ b/core/src/fxcodec/codec/fx_codec_icc.cpp
@@ -434,7 +434,8 @@
   CFX_ByteString ProfileKey(key.GetBuffer(), key.GetSize());
   ASSERT(pTransformKey);
   pTransformKey->AppendBlock(ProfileKey.GetBuffer(0), ProfileKey.GetLength());
-  if (!m_MapProfile.Lookup(ProfileKey, (void*&)pCache)) {
+  auto it = m_MapProfile.find(ProfileKey);
+  if (it == m_MapProfile.end()) {
     pCache = new CFX_IccProfileCache;
     switch (pIccParam->dwProfileType) {
       case Icc_PARAMTYPE_BUFFER:
@@ -456,8 +457,9 @@
       default:
         break;
     }
-    m_MapProfile.SetAt(ProfileKey, pCache);
+    m_MapProfile[ProfileKey] = pCache;
   } else {
+    pCache = it->second;
     pCache->m_dwRate++;
   }
   return pCache->m_pProfile;
@@ -496,7 +498,8 @@
       << (pProofProfile != NULL) << dwPrfIntent << dwPrfFlag;
   CFX_ByteStringC TransformKey(key.GetBuffer(), key.GetSize());
   CFX_IccTransformCache* pTransformCache;
-  if (!m_MapTranform.Lookup(TransformKey, (void*&)pTransformCache)) {
+  auto it = m_MapTranform.find(TransformKey);
+  if (it == m_MapTranform.end()) {
     pCmm = FX_Alloc(CLcmsCmm, 1);
     pCmm->m_nSrcComponents = T_CHANNELS(dwInputProfileType);
     pCmm->m_nDstComponents = T_CHANNELS(dwOutputProfileType);
@@ -512,26 +515,22 @@
                              dwOutputProfileType, dwIntent, dwFlag);
     }
     pCmm->m_hTransform = pTransformCache->m_pIccTransform;
-    m_MapTranform.SetAt(TransformKey, pTransformCache);
+    m_MapTranform[TransformKey] = pTransformCache;
   } else {
+    pTransformCache = it->second;
     pTransformCache->m_dwRate++;
   }
   return pTransformCache->m_pCmm;
 }
 CCodec_IccModule::~CCodec_IccModule() {
-  FX_POSITION pos = m_MapProfile.GetStartPosition();
-  CFX_ByteString key;
-  CFX_IccProfileCache* pProfileCache;
-  while (pos) {
-    m_MapProfile.GetNextAssoc(pos, key, (void*&)pProfileCache);
-    delete pProfileCache;
+  for (const auto& pair : m_MapProfile) {
+    delete pair.second;
   }
-  pos = m_MapTranform.GetStartPosition();
-  CFX_IccTransformCache* pTransformCache;
-  while (pos) {
-    m_MapTranform.GetNextAssoc(pos, key, (void*&)pTransformCache);
-    delete pTransformCache;
+  m_MapProfile.clear();
+  for (const auto& pair : m_MapTranform) {
+    delete pair.second;
   }
+  m_MapTranform.clear();
 }
 void* CCodec_IccModule::CreateTransform_sRGB(const uint8_t* pProfileData,
                                              FX_DWORD dwProfileSize,
diff --git a/core/src/fxcrt/fx_basic_maps.cpp b/core/src/fxcrt/fx_basic_maps.cpp
index 1558ae6..6bcb915 100644
--- a/core/src/fxcrt/fx_basic_maps.cpp
+++ b/core/src/fxcrt/fx_basic_maps.cpp
@@ -7,12 +7,6 @@
 #include "../../include/fxcrt/fx_basic.h"
 #include "plex.h"
 
-static void ConstructElement(CFX_ByteString* pNewData) {
-  new (pNewData) CFX_ByteString();
-}
-static void DestructElement(CFX_ByteString* pOldData) {
-  pOldData->~CFX_ByteString();
-}
 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize)
     : m_pHashTable(NULL),
       m_nHashTableSize(17),
@@ -165,192 +159,6 @@
     RemoveAll();
   }
 }
-CFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize)
-    : m_pHashTable(NULL),
-      m_nHashTableSize(17),
-      m_nCount(0),
-      m_pFreeList(NULL),
-      m_pBlocks(NULL),
-      m_nBlockSize(nBlockSize) {
-  ASSERT(m_nBlockSize > 0);
-}
-void CFX_MapByteStringToPtr::RemoveAll() {
-  if (m_pHashTable != NULL) {
-    for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) {
-      CAssoc* pAssoc;
-      for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL;
-           pAssoc = pAssoc->pNext) {
-        DestructElement(&pAssoc->key);
-      }
-    }
-    FX_Free(m_pHashTable);
-    m_pHashTable = NULL;
-  }
-  m_nCount = 0;
-  m_pFreeList = NULL;
-  m_pBlocks->FreeDataChain();
-  m_pBlocks = NULL;
-}
-CFX_MapByteStringToPtr::~CFX_MapByteStringToPtr() {
-  RemoveAll();
-  ASSERT(m_nCount == 0);
-}
-void CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition,
-                                          CFX_ByteString& rKey,
-                                          void*& rValue) const {
-  ASSERT(m_pHashTable != NULL);
-  CAssoc* pAssocRet = (CAssoc*)rNextPosition;
-  ASSERT(pAssocRet != NULL);
-  if (pAssocRet == (CAssoc*)-1) {
-    for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
-      if ((pAssocRet = m_pHashTable[nBucket]) != NULL) {
-        break;
-      }
-    ASSERT(pAssocRet != NULL);
-  }
-  CAssoc* pAssocNext;
-  if ((pAssocNext = pAssocRet->pNext) == NULL) {
-    for (FX_DWORD nBucket = pAssocRet->nHashValue + 1;
-         nBucket < m_nHashTableSize; nBucket++)
-      if ((pAssocNext = m_pHashTable[nBucket]) != NULL) {
-        break;
-      }
-  }
-  rNextPosition = (FX_POSITION)pAssocNext;
-  rKey = pAssocRet->key;
-  rValue = pAssocRet->value;
-}
-void* CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const {
-  ASSERT(m_pHashTable != NULL);
-  CAssoc* pAssocRet = (CAssoc*)rNextPosition;
-  ASSERT(pAssocRet != NULL);
-  if (pAssocRet == (CAssoc*)-1) {
-    for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
-      if ((pAssocRet = m_pHashTable[nBucket]) != NULL) {
-        break;
-      }
-    ASSERT(pAssocRet != NULL);
-  }
-  CAssoc* pAssocNext;
-  if ((pAssocNext = pAssocRet->pNext) == NULL) {
-    for (FX_DWORD nBucket = pAssocRet->nHashValue + 1;
-         nBucket < m_nHashTableSize; nBucket++)
-      if ((pAssocNext = m_pHashTable[nBucket]) != NULL) {
-        break;
-      }
-  }
-  rNextPosition = (FX_POSITION)pAssocNext;
-  return pAssocRet->value;
-}
-void*& CFX_MapByteStringToPtr::operator[](const CFX_ByteStringC& key) {
-  FX_DWORD nHash;
-  CAssoc* pAssoc;
-  if ((pAssoc = GetAssocAt(key, nHash)) == NULL) {
-    if (m_pHashTable == NULL) {
-      InitHashTable(m_nHashTableSize);
-    }
-    pAssoc = NewAssoc();
-    pAssoc->nHashValue = nHash;
-    pAssoc->key = key;
-    pAssoc->pNext = m_pHashTable[nHash];
-    m_pHashTable[nHash] = pAssoc;
-  }
-  return pAssoc->value;
-}
-CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::NewAssoc() {
-  if (m_pFreeList == NULL) {
-    CFX_Plex* newBlock = CFX_Plex::Create(
-        m_pBlocks, m_nBlockSize, sizeof(CFX_MapByteStringToPtr::CAssoc));
-    CFX_MapByteStringToPtr::CAssoc* pAssoc =
-        (CFX_MapByteStringToPtr::CAssoc*)newBlock->data();
-    pAssoc += m_nBlockSize - 1;
-    for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) {
-      pAssoc->pNext = m_pFreeList;
-      m_pFreeList = pAssoc;
-    }
-  }
-  ASSERT(m_pFreeList != NULL);
-  CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList;
-  m_pFreeList = m_pFreeList->pNext;
-  m_nCount++;
-  ASSERT(m_nCount > 0);
-  ConstructElement(&pAssoc->key);
-  pAssoc->value = 0;
-  return pAssoc;
-}
-void CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc) {
-  DestructElement(&pAssoc->key);
-  pAssoc->pNext = m_pFreeList;
-  m_pFreeList = pAssoc;
-  m_nCount--;
-  ASSERT(m_nCount >= 0);
-  if (m_nCount == 0) {
-    RemoveAll();
-  }
-}
-CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::GetAssocAt(
-    const CFX_ByteStringC& key,
-    FX_DWORD& nHash) const {
-  nHash = HashKey(key) % m_nHashTableSize;
-  if (m_pHashTable == NULL) {
-    return NULL;
-  }
-  CAssoc* pAssoc;
-  for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) {
-    if (pAssoc->key == key) {
-      return pAssoc;
-    }
-  }
-  return NULL;
-}
-FX_BOOL CFX_MapByteStringToPtr::Lookup(const CFX_ByteStringC& key,
-                                       void*& rValue) const {
-  FX_DWORD nHash;
-  CAssoc* pAssoc = GetAssocAt(key, nHash);
-  if (pAssoc == NULL) {
-    return FALSE;
-  }
-  rValue = pAssoc->value;
-  return TRUE;
-}
-void CFX_MapByteStringToPtr::InitHashTable(FX_DWORD nHashSize,
-                                           FX_BOOL bAllocNow) {
-  ASSERT(m_nCount == 0);
-  ASSERT(nHashSize > 0);
-  FX_Free(m_pHashTable);
-  m_pHashTable = NULL;
-  if (bAllocNow) {
-    m_pHashTable = FX_Alloc(CAssoc*, nHashSize);
-  }
-  m_nHashTableSize = nHashSize;
-}
-inline FX_DWORD CFX_MapByteStringToPtr::HashKey(
-    const CFX_ByteStringC& key) const {
-  FX_DWORD nHash = 0;
-  int len = key.GetLength();
-  const uint8_t* buf = key.GetPtr();
-  for (int i = 0; i < len; i++) {
-    nHash = (nHash << 5) + nHash + buf[i];
-  }
-  return nHash;
-}
-FX_BOOL CFX_MapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) {
-  if (m_pHashTable == NULL) {
-    return FALSE;
-  }
-  CAssoc** ppAssocPrev;
-  ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize];
-  CAssoc* pAssoc;
-  for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) {
-    if (pAssoc->key == key) {
-      *ppAssocPrev = pAssoc->pNext;
-      FreeAssoc(pAssoc);
-      return TRUE;
-    }
-    ppAssocPrev = &pAssoc->pNext;
-  }
-  return FALSE;
-}
 struct _CompactString {
   uint8_t m_CompactLen;
   uint8_t m_LenHigh;
diff --git a/core/src/fxge/apple/fx_mac_imp.cpp b/core/src/fxge/apple/fx_mac_imp.cpp
index e08f622..88a51bd 100644
--- a/core/src/fxge/apple/fx_mac_imp.cpp
+++ b/core/src/fxge/apple/fx_mac_imp.cpp
@@ -65,10 +65,10 @@
   if (iBaseFont < 12) {
     return GetFont(face);
   }
-  void* p;
-  if (m_FontList.Lookup(face, p)) {
-    return p;
-  }
+  auto it = m_FontList.find(face);
+  if (it != m_FontList.end())
+    return it->second;
+
   if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
     return GetFont("Courier New");
   }
@@ -88,9 +88,10 @@
     case FXFONT_CHINESEBIG5_CHARSET:
       face = "LiSong Pro Light";
   }
-  if (m_FontList.Lookup(face, p)) {
-    return p;
-  }
+  it = m_FontList.find(face);
+  if (it != m_FontList.end())
+    return it->second;
+
   return NULL;
 }
 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() {
diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp
index f755b69..686e941 100644
--- a/core/src/fxge/ge/fx_ge_fontmap.cpp
+++ b/core/src/fxge/ge/fx_ge_fontmap.cpp
@@ -9,9 +9,31 @@
 #include "../../../include/fxge/fx_ge.h"
 #include "../../../include/fxge/fx_freetype.h"
 #include "text_int.h"
+
 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1])
 #define GET_TT_LONG(w) \
   (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
+
+namespace {
+
+CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name,
+                               int weight,
+                               FX_BOOL bItalic) {
+  CFX_ByteString key(face_name);
+  key += ',';
+  key += CFX_ByteString::FormatInteger(weight);
+  key += bItalic ? 'I' : 'N';
+  return key;
+}
+
+CFX_ByteString KeyNameFromSize(int ttc_size, FX_DWORD checksum) {
+  CFX_ByteString key;
+  key.Format("%d:%d", ttc_size, checksum);
+  return key;
+}
+
+}  // namespace
+
 CFX_SubstFont::CFX_SubstFont() {
   m_ExtHandle = NULL;
   m_Charset = 0;
@@ -74,14 +96,10 @@
   }
 }
 void CFX_FontMgr::FreeCache() {
-  FX_POSITION pos = m_FaceMap.GetStartPosition();
-  while (pos) {
-    CFX_ByteString Key;
-    CTTFontDesc* face;
-    m_FaceMap.GetNextAssoc(pos, Key, (void*&)face);
-    delete face;
+  for (const auto& pair : m_FaceMap) {
+    delete pair.second;
   }
-  m_FaceMap.RemoveAll();
+  m_FaceMap.clear();
 }
 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) {
   m_pBuiltinMapper->SetSystemFontInfo(pFontInfo);
@@ -103,18 +121,14 @@
                                      int weight,
                                      FX_BOOL bItalic,
                                      uint8_t*& pFontData) {
-  CFX_ByteString key(face_name);
-  key += ',';
-  key += CFX_ByteString::FormatInteger(weight);
-  key += bItalic ? 'I' : 'N';
-  CTTFontDesc* pFontDesc = NULL;
-  m_FaceMap.Lookup(key, (void*&)pFontDesc);
-  if (pFontDesc) {
-    pFontData = pFontDesc->m_pFontData;
-    pFontDesc->m_RefCount++;
-    return pFontDesc->m_SingleFace.m_pFace;
-  }
-  return NULL;
+  auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
+  if (it == m_FaceMap.end())
+    return nullptr;
+
+  CTTFontDesc* pFontDesc = it->second;
+  pFontData = pFontDesc->m_pFontData;
+  pFontDesc->m_RefCount++;
+  return pFontDesc->m_SingleFace.m_pFace;
 }
 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
                                      int weight,
@@ -148,11 +162,7 @@
     delete pFontDesc;
     return NULL;
   }
-  CFX_ByteString key(face_name);
-  key += ',';
-  key += CFX_ByteString::FormatInteger(weight);
-  key += bItalic ? 'I' : 'N';
-  m_FaceMap.SetAt(key, pFontDesc);
+  m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc;
   return pFontDesc->m_SingleFace.m_pFace;
 }
 const FX_CHAR* const g_Base14FontNames[14] = {
@@ -305,17 +315,15 @@
                                         FX_DWORD checksum,
                                         int font_offset,
                                         uint8_t*& pFontData) {
-  CFX_ByteString key;
-  key.Format("%d:%d", ttc_size, checksum);
-  CTTFontDesc* pFontDesc = NULL;
-  m_FaceMap.Lookup(key, (void*&)pFontDesc);
-  if (pFontDesc == NULL) {
-    return NULL;
-  }
+  auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
+  if (it == m_FaceMap.end())
+    return nullptr;
+
+  CTTFontDesc* pFontDesc = it->second;
   pFontData = pFontDesc->m_pFontData;
   pFontDesc->m_RefCount++;
   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
-  if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) {
+  if (!pFontDesc->m_TTCFace.m_pFaces[face_index]) {
     pFontDesc->m_TTCFace.m_pFaces[face_index] =
         GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
   }
@@ -326,8 +334,6 @@
                                         uint8_t* pData,
                                         FX_DWORD size,
                                         int font_offset) {
-  CFX_ByteString key;
-  key.Format("%d:%d", ttc_size, checksum);
   CTTFontDesc* pFontDesc = new CTTFontDesc;
   if (!pFontDesc) {
     return NULL;
@@ -338,8 +344,7 @@
     pFontDesc->m_TTCFace.m_pFaces[i] = NULL;
   }
   pFontDesc->m_RefCount++;
-  key.Format("%d:%d", ttc_size, checksum);
-  m_FaceMap.SetAt(key, pFontDesc);
+  m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = pFontDesc;
   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
   pFontDesc->m_TTCFace.m_pFaces[face_index] =
       GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
@@ -382,18 +387,16 @@
   return face;
 }
 void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
-  if (face == NULL) {
+  if (!face) {
     return;
   }
-  FX_POSITION pos = m_FaceMap.GetStartPosition();
   FX_BOOL bNeedFaceDone = TRUE;
-  while (pos) {
-    CFX_ByteString Key;
-    CTTFontDesc* ttface;
-    m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface);
-    int nRet = ttface->ReleaseFace(face);
+  auto it = m_FaceMap.begin();
+  while (it != m_FaceMap.end()) {
+    auto temp = it++;
+    int nRet = temp->second->ReleaseFace(face);
     if (nRet == 0) {
-      m_FaceMap.RemoveKey(Key);
+      m_FaceMap.erase(temp);
       bNeedFaceDone = FALSE;
     } else if (nRet > 0) {
       bNeedFaceDone = FALSE;
@@ -1373,12 +1376,8 @@
 #endif
 CFX_FolderFontInfo::CFX_FolderFontInfo() {}
 CFX_FolderFontInfo::~CFX_FolderFontInfo() {
-  FX_POSITION pos = m_FontList.GetStartPosition();
-  while (pos) {
-    CFX_ByteString key;
-    void* value;
-    m_FontList.GetNextAssoc(pos, key, value);
-    delete (CFX_FontFaceInfo*)value;
+  for (const auto& pair : m_FontList) {
+    delete pair.second;
   }
 }
 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) {
@@ -1488,8 +1487,7 @@
   if (style != "Regular") {
     facename += " " + style;
   }
-  void* p;
-  if (m_FontList.Lookup(facename, p)) {
+  if (m_FontList.find(facename) != m_FontList.end()) {
     return;
   }
   CFX_FontFaceInfo* pInfo =
@@ -1533,7 +1531,7 @@
   if (facename.Find(FX_BSTRC("Serif")) > -1) {
     pInfo->m_Styles |= FXFONT_SERIF;
   }
-  m_FontList.SetAt(facename, pInfo);
+  m_FontList[facename] = pInfo;
 }
 void* CFX_FolderFontInfo::MapFont(int weight,
                                   FX_BOOL bItalic,
@@ -1550,11 +1548,8 @@
   return NULL;
 }
 void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) {
-  void* p;
-  if (!m_FontList.Lookup(face, p)) {
-    return NULL;
-  }
-  return p;
+  auto it = m_FontList.find(face);
+  return it != m_FontList.end() ? it->second : nullptr;
 }
 FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont,
                                          FX_DWORD table,
diff --git a/core/src/fxge/ge/fx_ge_linux.cpp b/core/src/fxge/ge/fx_ge_linux.cpp
index bad3854..4e713dc 100644
--- a/core/src/fxge/ge/fx_ge_linux.cpp
+++ b/core/src/fxge/ge/fx_ge_linux.cpp
@@ -105,7 +105,6 @@
   if (iBaseFont < 12) {
     return GetFont(face);
   }
-  void* p = NULL;
   FX_BOOL bCJK = TRUE;
   switch (charset) {
     case FXFONT_SHIFTJIS_CHARSET: {
@@ -113,34 +112,36 @@
       if (index < 0) {
         break;
       }
-      for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++)
-        if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) {
-          return p;
+      for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++) {
+        auto it = m_FontList.find(LinuxGpFontList[index].NameArr[i]);
+        if (it != m_FontList.end()) {
+          return it->second;
         }
+      }
     } break;
     case FXFONT_GB2312_CHARSET: {
-      static int32_t s_gbCount =
-          sizeof(g_LinuxGbFontList) / sizeof(const FX_CHAR*);
-      for (int32_t i = 0; i < s_gbCount; i++)
-        if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) {
-          return p;
+      for (int32_t i = 0; i < FX_ArraySize(g_LinuxGbFontList); ++i) {
+        auto it = m_FontList.find(g_LinuxGbFontList[i]);
+        if (it != m_FontList.end()) {
+          return it->second;
         }
+      }
     } break;
     case FXFONT_CHINESEBIG5_CHARSET: {
-      static int32_t s_b5Count =
-          sizeof(g_LinuxB5FontList) / sizeof(const FX_CHAR*);
-      for (int32_t i = 0; i < s_b5Count; i++)
-        if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) {
-          return p;
+      for (int32_t i = 0; i < FX_ArraySize(g_LinuxB5FontList); ++i) {
+        auto it = m_FontList.find(g_LinuxB5FontList[i]);
+        if (it != m_FontList.end()) {
+          return it->second;
         }
+      }
     } break;
     case FXFONT_HANGEUL_CHARSET: {
-      static int32_t s_hgCount =
-          sizeof(g_LinuxHGFontList) / sizeof(const FX_CHAR*);
-      for (int32_t i = 0; i < s_hgCount; i++)
-        if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) {
-          return p;
+      for (int32_t i = 0; i < FX_ArraySize(g_LinuxHGFontList); ++i) {
+        auto it = m_FontList.find(g_LinuxHGFontList[i]);
+        if (it != m_FontList.end()) {
+          return it->second;
         }
+      }
     } break;
     default:
       bCJK = FALSE;
@@ -201,11 +202,9 @@
   CFX_FontFaceInfo* pFind = NULL;
   FX_DWORD charset_flag = _LinuxGetCharset(charset);
   int32_t iBestSimilar = 0;
-  FX_POSITION pos = m_FontList.GetStartPosition();
-  while (pos) {
-    CFX_ByteString bsName;
-    CFX_FontFaceInfo* pFont = NULL;
-    m_FontList.GetNextAssoc(pos, bsName, (void*&)pFont);
+  for (const auto& it : m_FontList) {
+    const CFX_ByteString& bsName = it.first;
+    CFX_FontFaceInfo* pFont = it.second;
     if (!(pFont->m_Charsets & charset_flag) &&
         charset != FXFONT_DEFAULT_CHARSET) {
       continue;
diff --git a/core/src/fxge/ge/fx_ge_text.cpp b/core/src/fxge/ge/fx_ge_text.cpp
index 0bb8eab..93e3486 100644
--- a/core/src/fxge/ge/fx_ge_text.cpp
+++ b/core/src/fxge/ge/fx_ge_text.cpp
@@ -1204,15 +1204,11 @@
   m_Face = face;
 }
 CFX_FaceCache::~CFX_FaceCache() {
-  FX_POSITION pos = m_SizeMap.GetStartPosition();
-  CFX_ByteString Key;
-  CFX_SizeGlyphCache* pSizeCache = NULL;
-  while (pos) {
-    m_SizeMap.GetNextAssoc(pos, Key, (void*&)pSizeCache);
-    delete pSizeCache;
+  for (const auto& pair : m_SizeMap) {
+    delete pair.second;
   }
-  m_SizeMap.RemoveAll();
-  pos = m_PathMap.GetStartPosition();
+  m_SizeMap.clear();
+  FX_POSITION pos = m_PathMap.GetStartPosition();
   void* key1;
   CFX_PathData* pPath;
   while (pos) {
@@ -1232,13 +1228,13 @@
     FX_BOOL bFontStyle,
     int dest_width,
     int anti_alias) {
-  CFX_SizeGlyphCache* pSizeCache = NULL;
-  if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
+  CFX_SizeGlyphCache* pSizeCache;
+  auto it = m_SizeMap.find(FaceGlyphsKey);
+  if (it == m_SizeMap.end()) {
     pSizeCache = new CFX_SizeGlyphCache;
-    if (pSizeCache == NULL) {
-      return NULL;
-    }
-    m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
+    m_SizeMap[FaceGlyphsKey] = pSizeCache;
+  } else {
+    pSizeCache = it->second;
   }
   CFX_GlyphBitmap* pGlyphBitmap = NULL;
   if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index,
@@ -1310,8 +1306,9 @@
                              bFontStyle, dest_width, anti_alias);
   }
   CFX_GlyphBitmap* pGlyphBitmap;
-  CFX_SizeGlyphCache* pSizeCache = NULL;
-  if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
+  auto it = m_SizeMap.find(FaceGlyphsKey);
+  if (it != m_SizeMap.end()) {
+    CFX_SizeGlyphCache* pSizeCache = it->second;
     if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index,
                                       (void*&)pGlyphBitmap)) {
       return pGlyphBitmap;
@@ -1326,8 +1323,8 @@
     pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix,
                                           dest_width, anti_alias);
     if (pGlyphBitmap) {
-      pSizeCache = new CFX_SizeGlyphCache;
-      m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
+      CFX_SizeGlyphCache* pSizeCache = new CFX_SizeGlyphCache;
+      m_SizeMap[FaceGlyphsKey] = pSizeCache;
       pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap);
       return pGlyphBitmap;
     }
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
index 27e7a91..1ddb990 100644
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
@@ -40,7 +40,6 @@
 

   void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect);

 

- public:

   virtual void SetChangeMark(IXFA_Doc* hDoc);

   virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc);

   // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.

@@ -220,16 +219,9 @@
   IXFA_Doc* m_pXFADoc;

   IXFA_DocView* m_pXFADocView;

   CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;

-

   CPDFSDK_Document* m_pSDKDoc;

   CPDFXFA_App* m_pApp;

-

-  CFX_MapByteStringToPtr m_XfaGlobalProperty;

-

-  CFX_MapByteStringToPtr m_ValueMap;

-

   IFXJS_Context* m_pJSContext;

-

   int m_iDocType;

 };

 

diff --git a/fpdfsdk/include/fsdk_annothandler.h b/fpdfsdk/include/fsdk_annothandler.h
index 266c458..c15681d 100644
--- a/fpdfsdk/include/fsdk_annothandler.h
+++ b/fpdfsdk/include/fsdk_annothandler.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_INCLUDE_FSDK_ANNOTHANDLER_H_
 #define FPDFSDK_INCLUDE_FSDK_ANNOTHANDLER_H_
 
+#include <map>
+
 #include "../../core/include/fxcrt/fx_basic.h"
 
 #define FSDK_XFAWIDGET_TYPENAME "XFAWidget"
@@ -427,7 +429,7 @@
 
  private:
   CBA_AnnotHandlerArray m_Handlers;
-  CFX_MapByteStringToPtr m_mapType2Handler;
+  std::map<CFX_ByteString, IPDFSDK_AnnotHandler*> m_mapType2Handler;
   CPDFDoc_Environment* m_pApp;
 };
 
diff --git a/fpdfsdk/include/javascript/global.h b/fpdfsdk/include/javascript/global.h
index e881625..7f78bb6 100644
--- a/fpdfsdk/include/javascript/global.h
+++ b/fpdfsdk/include/javascript/global.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_INCLUDE_JAVASCRIPT_GLOBAL_H_
 #define FPDFSDK_INCLUDE_JAVASCRIPT_GLOBAL_H_
 
+#include <map>
+
 #include "JS_Define.h"
 
 class CJS_GlobalData;
@@ -69,7 +71,7 @@
   void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData);
 
  private:
-  CFX_MapByteStringToPtr m_mapGlobal;
+  std::map<CFX_ByteString, JSGlobalData*> m_mapGlobal;
   CFX_WideString m_sFilePath;
   CJS_GlobalData* m_pGlobalData;
   CPDFDoc_Environment* m_pApp;
diff --git a/fpdfsdk/src/fsdk_annothandler.cpp b/fpdfsdk/src/fsdk_annothandler.cpp
index 55d4629..287a26b 100644
--- a/fpdfsdk/src/fsdk_annothandler.cpp
+++ b/fpdfsdk/src/fsdk_annothandler.cpp
@@ -29,25 +29,20 @@
     delete pHandler;
   }
   m_Handlers.RemoveAll();
-  m_mapType2Handler.RemoveAll();
+  m_mapType2Handler.clear();
 }
 
 void CPDFSDK_AnnotHandlerMgr::RegisterAnnotHandler(
     IPDFSDK_AnnotHandler* pAnnotHandler) {
-  ASSERT(pAnnotHandler != NULL);
-
-  ASSERT(GetAnnotHandler(pAnnotHandler->GetType()) == NULL);
+  ASSERT(!GetAnnotHandler(pAnnotHandler->GetType()));
 
   m_Handlers.Add(pAnnotHandler);
-  m_mapType2Handler.SetAt(pAnnotHandler->GetType(), (void*)pAnnotHandler);
+  m_mapType2Handler[pAnnotHandler->GetType()] = pAnnotHandler;
 }
 
 void CPDFSDK_AnnotHandlerMgr::UnRegisterAnnotHandler(
     IPDFSDK_AnnotHandler* pAnnotHandler) {
-  ASSERT(pAnnotHandler != NULL);
-
-  m_mapType2Handler.RemoveKey(pAnnotHandler->GetType());
-
+  m_mapType2Handler.erase(pAnnotHandler->GetType());
   for (int i = 0, sz = m_Handlers.GetSize(); i < sz; i++) {
     if (m_Handlers.GetAt(i) == pAnnotHandler) {
       m_Handlers.RemoveAt(i);
@@ -131,9 +126,8 @@
 
 IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
     const CFX_ByteString& sType) const {
-  void* pRet = NULL;
-  m_mapType2Handler.Lookup(sType, pRet);
-  return (IPDFSDK_AnnotHandler*)pRet;
+  auto it = m_mapType2Handler.find(sType);
+  return it != m_mapType2Handler.end() ? it->second : nullptr;
 }
 
 void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
diff --git a/fpdfsdk/src/javascript/global.cpp b/fpdfsdk/src/javascript/global.cpp
index f03c4d1..dea2b58 100644
--- a/fpdfsdk/src/javascript/global.cpp
+++ b/fpdfsdk/src/javascript/global.cpp
@@ -127,15 +127,12 @@
 FX_BOOL JSGlobalAlternate::DelProperty(IFXJS_Context* cc,
                                        const FX_WCHAR* propname,
                                        CFX_WideString& sError) {
-  JSGlobalData* pData = NULL;
-  CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
+  auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
+  if (it == m_mapGlobal.end())
+    return FALSE;
 
-  if (m_mapGlobal.Lookup(sPropName, (void*&)pData)) {
-    pData->bDeleted = TRUE;
-    return TRUE;
-  }
-
-  return FALSE;
+  it->second->bDeleted = TRUE;
+  return TRUE;
 }
 
 FX_BOOL JSGlobalAlternate::DoProperty(IFXJS_Context* cc,
@@ -181,19 +178,16 @@
         break;
     }
   } else {
-    void* pVoid = nullptr;
-    if (!m_mapGlobal.Lookup(CFX_ByteString::FromUnicode(propname), pVoid)) {
+    auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
+    if (it == m_mapGlobal.end()) {
       vp.SetNull();
       return TRUE;
     }
-    if (!pVoid) {
+    JSGlobalData* pData = it->second;
+    if (pData->bDeleted) {
       vp.SetNull();
       return TRUE;
     }
-    JSGlobalData* pData = (JSGlobalData*)pVoid;
-    if (pData->bDeleted)
-      return TRUE;
-
     switch (pData->nType) {
       case JS_GLOBALDATA_TYPE_NUMBER:
         vp << pData->dData;
@@ -230,11 +224,10 @@
     return FALSE;
   }
 
-  CFX_ByteString sName = params[0].ToCFXByteString();
-
-  JSGlobalData* pData = NULL;
-  if (m_mapGlobal.Lookup(sName, (void*&)pData)) {
-    if (pData && !pData->bDeleted) {
+  auto it = m_mapGlobal.find(params[0].ToCFXByteString());
+  if (it != m_mapGlobal.end()) {
+    JSGlobalData* pData = it->second;
+    if (!pData->bDeleted) {
       pData->bPersistent = params[1].ToBool();
       return TRUE;
     }
@@ -300,52 +293,42 @@
 }
 
 void JSGlobalAlternate::CommitGlobalPersisitentVariables() {
-  ASSERT(m_pGlobalData != NULL);
-
-  FX_POSITION pos = m_mapGlobal.GetStartPosition();
-  while (pos) {
-    CFX_ByteString name;
-    JSGlobalData* pData = NULL;
-    m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);
-
-    if (pData) {
-      if (pData->bDeleted) {
-        m_pGlobalData->DeleteGlobalVariable(name);
-      } else {
-        switch (pData->nType) {
-          case JS_GLOBALDATA_TYPE_NUMBER:
-            m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
+  ASSERT(m_pGlobalData);
+  for (auto it = m_mapGlobal.begin(); it != m_mapGlobal.end(); ++it) {
+    CFX_ByteString name = it->first;
+    JSGlobalData* pData = it->second;
+    if (pData->bDeleted) {
+      m_pGlobalData->DeleteGlobalVariable(name);
+    } else {
+      switch (pData->nType) {
+        case JS_GLOBALDATA_TYPE_NUMBER:
+          m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GLOBALDATA_TYPE_BOOLEAN:
+          m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GLOBALDATA_TYPE_STRING:
+          m_pGlobalData->SetGlobalVariableString(name, pData->sData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GLOBALDATA_TYPE_OBJECT:
+          // if (pData->pData)
+          {
+            CJS_GlobalVariableArray array;
+            v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
+                GetJSObject()->GetIsolate(), pData->pData);
+            ObjectToArray(obj, array);
+            m_pGlobalData->SetGlobalVariableObject(name, array);
             m_pGlobalData->SetGlobalVariablePersistent(name,
                                                        pData->bPersistent);
-            break;
-          case JS_GLOBALDATA_TYPE_BOOLEAN:
-            m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
-            m_pGlobalData->SetGlobalVariablePersistent(name,
-                                                       pData->bPersistent);
-            break;
-          case JS_GLOBALDATA_TYPE_STRING:
-            m_pGlobalData->SetGlobalVariableString(name, pData->sData);
-            m_pGlobalData->SetGlobalVariablePersistent(name,
-                                                       pData->bPersistent);
-            break;
-          case JS_GLOBALDATA_TYPE_OBJECT:
-            // if (pData->pData)
-            {
-              CJS_GlobalVariableArray array;
-              v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
-                  GetJSObject()->GetIsolate(), pData->pData);
-              ObjectToArray(obj, array);
-              m_pGlobalData->SetGlobalVariableObject(name, array);
-              m_pGlobalData->SetGlobalVariablePersistent(name,
-                                                         pData->bPersistent);
-            }
-            break;
-          case JS_GLOBALDATA_TYPE_NULL:
-            m_pGlobalData->SetGlobalVariableNull(name);
-            m_pGlobalData->SetGlobalVariablePersistent(name,
-                                                       pData->bPersistent);
-            break;
-        }
+          }
+          break;
+        case JS_GLOBALDATA_TYPE_NULL:
+          m_pGlobalData->SetGlobalVariableNull(name);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
       }
     }
   }
@@ -449,15 +432,10 @@
 }
 
 void JSGlobalAlternate::DestroyGlobalPersisitentVariables() {
-  FX_POSITION pos = m_mapGlobal.GetStartPosition();
-  while (pos) {
-    CFX_ByteString name;
-    JSGlobalData* pData = NULL;
-    m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);
-    delete pData;
+  for (const auto& pair : m_mapGlobal) {
+    delete pair.second;
   }
-
-  m_mapGlobal.RemoveAll();
+  m_mapGlobal.clear();
 }
 
 FX_BOOL JSGlobalAlternate::SetGlobalVariables(const FX_CHAR* propname,
@@ -467,13 +445,12 @@
                                               const CFX_ByteString& sData,
                                               JSObject pData,
                                               bool bDefaultPersistent) {
-  if (propname == NULL)
+  if (!propname)
     return FALSE;
 
-  JSGlobalData* pTemp = NULL;
-  m_mapGlobal.Lookup(propname, (void*&)pTemp);
-
-  if (pTemp) {
+  auto it = m_mapGlobal.find(propname);
+  if (it != m_mapGlobal.end()) {
+    JSGlobalData* pTemp = it->second;
     if (pTemp->bDeleted || pTemp->nType != nType) {
       pTemp->dData = 0;
       pTemp->bData = 0;
@@ -482,7 +459,6 @@
     }
 
     pTemp->bDeleted = FALSE;
-
     switch (nType) {
       case JS_GLOBALDATA_TYPE_NUMBER: {
         pTemp->dData = dData;
@@ -501,7 +477,6 @@
       default:
         return FALSE;
     }
-
     return TRUE;
   }
 
@@ -541,8 +516,7 @@
       return FALSE;
   }
 
-  m_mapGlobal.SetAt(propname, (void*)pNewData);
-
+  m_mapGlobal[propname] = pNewData;
   return TRUE;
 }
 
diff --git a/xfa/src/fdp/src/css/fde_csscache.cpp b/xfa/src/fdp/src/css/fde_csscache.cpp
index 8c56680..b047586 100644
--- a/xfa/src/fdp/src/css/fde_csscache.cpp
+++ b/xfa/src/fdp/src/css/fde_csscache.cpp
@@ -17,21 +17,16 @@
 IFDE_CSSStyleSheetCache* IFDE_CSSStyleSheetCache::Create() {

   return new CFDE_CSSStyleSheetCache;

 }

+

 CFDE_CSSStyleSheetCache::CFDE_CSSStyleSheetCache()

     : m_pFixedStore(NULL), m_iMaxItems(5) {}

+

 CFDE_CSSStyleSheetCache::~CFDE_CSSStyleSheetCache() {

-  FX_POSITION pos = m_Stylesheets.GetStartPosition();

-  if (pos != NULL) {

-    CFX_ByteString szKey;

-    void* pValue;

-    while (pos != NULL) {

-      m_Stylesheets.GetNextAssoc(pos, szKey, pValue);

-      FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore,

-                     (FDE_LPCSSCACHEITEM)pValue);

-    }

-    m_Stylesheets.RemoveAll();

+  for (const auto& pair : m_Stylesheets) {

+    FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, pair.second);

   }

-  if (m_pFixedStore != NULL) {

+  m_Stylesheets.clear();

+  if (m_pFixedStore) {

     m_pFixedStore->Release();

   }

 }

@@ -43,9 +38,9 @@
         FX_ALLOCTYPE_Fixed, FX_MAX(10, m_iMaxItems), sizeof(FDE_CSSCACHEITEM));

     FXSYS_assert(m_pFixedStore != NULL);

   }

-  void* pValue = NULL;

-  if (m_Stylesheets.Lookup(szKey, pValue)) {

-    FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;

+  auto it = m_Stylesheets.find(szKey);

+  if (it != m_Stylesheets.end()) {

+    FDE_LPCSSCACHEITEM pItem = it->second;

     if (pItem->pStylesheet != pStyleSheet) {

       pItem->pStylesheet->Release();

       pItem->pStylesheet = pStyleSheet;

@@ -53,56 +48,48 @@
       pItem->dwActivity = 0;

     }

   } else {

-    while (m_Stylesheets.GetCount() >= m_iMaxItems) {

+    while (static_cast<int32_t>(m_Stylesheets.size()) >= m_iMaxItems) {

       RemoveLowestActivityItem();

     }

-    FDE_LPCSSCACHEITEM pItem =

+    m_Stylesheets[szKey] =

         FDE_NewWith(m_pFixedStore) FDE_CSSCACHEITEM(pStyleSheet);

-    FXSYS_assert(pItem != NULL);

-    m_Stylesheets.SetAt(szKey, pItem);

   }

 }

 IFDE_CSSStyleSheet* CFDE_CSSStyleSheetCache::GetStyleSheet(

     const CFX_ByteStringC& szKey) const {

-  void* pValue = NULL;

-  if (m_Stylesheets.Lookup(szKey, pValue)) {

-    FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;

-    pItem->dwActivity++;

-    pItem->pStylesheet->AddRef();

-    return pItem->pStylesheet;

+  auto it = m_Stylesheets.find(szKey);

+  if (it == m_Stylesheets.end()) {

+    return nullptr;

   }

-  return NULL;

+  FDE_LPCSSCACHEITEM pItem = it->second;

+  pItem->dwActivity++;

+  pItem->pStylesheet->AddRef();

+  return pItem->pStylesheet;

 }

 void CFDE_CSSStyleSheetCache::RemoveStyleSheet(const CFX_ByteStringC& szKey) {

-  void* pValue = NULL;

-  if (!m_Stylesheets.Lookup(szKey, pValue)) {

+  auto it = m_Stylesheets.find(szKey);

+  if (it == m_Stylesheets.end()) {

     return;

   }

-  FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, (FDE_LPCSSCACHEITEM)pValue);

-  m_Stylesheets.RemoveKey(szKey);

+  FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, it->second);

+  m_Stylesheets.erase(it);

 }

 void CFDE_CSSStyleSheetCache::RemoveLowestActivityItem() {

-  FX_POSITION pos = m_Stylesheets.GetStartPosition();

-  CFX_ByteString szKey;

-  void* pValue;

-  FDE_LPCSSCACHEITEM pItem = NULL;

-  CFX_ByteString szItem;

-  while (pos != NULL) {

-    m_Stylesheets.GetNextAssoc(pos, szKey, pValue);

-    switch (szKey.GetID()) {

+  auto found = m_Stylesheets.end();

+  for (auto it = m_Stylesheets.begin(); it != m_Stylesheets.end(); ++it) {

+    switch (it->first.GetID()) {

       case FXBSTR_ID('#', 'U', 'S', 'E'):

       case FXBSTR_ID('#', 'A', 'G', 'E'):

         continue;

     }

-    FDE_LPCSSCACHEITEM p = (FDE_LPCSSCACHEITEM)pValue;

-    if (pItem == NULL || pItem->dwActivity > p->dwActivity) {

-      szItem = szKey;

-      pItem = p;

+    if (found == m_Stylesheets.end() ||

+        it->second->dwActivity > found->second->dwActivity) {

+      found = it;

     }

   }

-  if (pItem != NULL) {

-    FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, pItem);

-    m_Stylesheets.RemoveKey(szItem);

+  if (found != m_Stylesheets.end()) {

+    FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, found->second);

+    m_Stylesheets.erase(found);

   }

 }

 _FDE_CSSTAGCACHE::_FDE_CSSTAGCACHE(_FDE_CSSTAGCACHE* parent,

diff --git a/xfa/src/fdp/src/css/fde_csscache.h b/xfa/src/fdp/src/css/fde_csscache.h
index a5b85b7..fd113a2 100644
--- a/xfa/src/fdp/src/css/fde_csscache.h
+++ b/xfa/src/fdp/src/css/fde_csscache.h
@@ -32,7 +32,7 @@
 

  protected:

   void RemoveLowestActivityItem();

-  CFX_MapByteStringToPtr m_Stylesheets;

+  std::map<CFX_ByteString, FDE_LPCSSCACHEITEM> m_Stylesheets;

   IFX_MEMAllocator* m_pFixedStore;

   int32_t m_iMaxItems;

 };