| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2014 PDFium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |  | 
| 6 |  | 
| 7 #include "xfa/src/fee/fx_wordbreak/fx_wordbreak_impl.h" |  | 
| 8 |  | 
| 9 FX_WordBreakProp FX_GetWordBreakProperty(FX_WCHAR wcCodePoint) { |  | 
| 10   FX_DWORD dwProperty = |  | 
| 11       (FX_DWORD)gs_FX_WordBreak_CodePointProperties[wcCodePoint >> 1]; |  | 
| 12   return (FX_WordBreakProp)(((wcCodePoint) & 1) ? (dwProperty & 0x0F) |  | 
| 13                                                   : (dwProperty >> 4)); |  | 
| 14 } |  | 
| 15 CFX_CharIter::CFX_CharIter(const CFX_WideString& wsText) |  | 
| 16     : m_wsText(wsText), m_nIndex(0) { |  | 
| 17   FXSYS_assert(!wsText.IsEmpty()); |  | 
| 18 } |  | 
| 19 CFX_CharIter::~CFX_CharIter() {} |  | 
| 20 void CFX_CharIter::Release() { |  | 
| 21   delete this; |  | 
| 22 } |  | 
| 23 FX_BOOL CFX_CharIter::Next(FX_BOOL bPrev) { |  | 
| 24   if (bPrev) { |  | 
| 25     if (m_nIndex <= 0) { |  | 
| 26       return FALSE; |  | 
| 27     } |  | 
| 28     m_nIndex--; |  | 
| 29   } else { |  | 
| 30     if (m_nIndex + 1 >= m_wsText.GetLength()) { |  | 
| 31       return FALSE; |  | 
| 32     } |  | 
| 33     m_nIndex++; |  | 
| 34   } |  | 
| 35   return TRUE; |  | 
| 36 } |  | 
| 37 FX_WCHAR CFX_CharIter::GetChar() { |  | 
| 38   return m_wsText.GetAt(m_nIndex); |  | 
| 39 } |  | 
| 40 void CFX_CharIter::SetAt(int32_t nIndex) { |  | 
| 41   if (nIndex < 0 || nIndex >= m_wsText.GetLength()) { |  | 
| 42     return; |  | 
| 43   } |  | 
| 44   m_nIndex = nIndex; |  | 
| 45 } |  | 
| 46 int32_t CFX_CharIter::GetAt() const { |  | 
| 47   return m_nIndex; |  | 
| 48 } |  | 
| 49 FX_BOOL CFX_CharIter::IsEOF(FX_BOOL bTail) const { |  | 
| 50   return bTail ? (m_nIndex + 1 == m_wsText.GetLength()) : (m_nIndex == 0); |  | 
| 51 } |  | 
| 52 IFX_CharIter* CFX_CharIter::Clone() { |  | 
| 53   CFX_CharIter* pIter = new CFX_CharIter(m_wsText); |  | 
| 54   pIter->m_nIndex = m_nIndex; |  | 
| 55   return pIter; |  | 
| 56 } |  | 
| 57 CFX_WordBreak::CFX_WordBreak() : m_pPreIter(NULL), m_pCurIter(NULL) {} |  | 
| 58 CFX_WordBreak::~CFX_WordBreak() { |  | 
| 59   if (m_pPreIter) { |  | 
| 60     m_pPreIter->Release(); |  | 
| 61     m_pPreIter = NULL; |  | 
| 62   } |  | 
| 63   if (m_pCurIter) { |  | 
| 64     m_pCurIter->Release(); |  | 
| 65     m_pCurIter = NULL; |  | 
| 66   } |  | 
| 67 } |  | 
| 68 void CFX_WordBreak::Release() { |  | 
| 69   delete this; |  | 
| 70 } |  | 
| 71 void CFX_WordBreak::Attach(IFX_CharIter* pIter) { |  | 
| 72   FXSYS_assert(pIter); |  | 
| 73   m_pCurIter = pIter; |  | 
| 74 } |  | 
| 75 void CFX_WordBreak::Attach(const CFX_WideString& wsText) { |  | 
| 76   m_pCurIter = new CFX_CharIter(wsText); |  | 
| 77 } |  | 
| 78 FX_BOOL CFX_WordBreak::Next(FX_BOOL bPrev) { |  | 
| 79   IFX_CharIter* pIter = bPrev ? m_pPreIter->Clone() : m_pCurIter->Clone(); |  | 
| 80   if (pIter->IsEOF(!bPrev)) { |  | 
| 81     return FALSE; |  | 
| 82   } |  | 
| 83   pIter->Next(bPrev); |  | 
| 84   if (!FindNextBreakPos(pIter, bPrev, TRUE)) { |  | 
| 85     pIter->Release(); |  | 
| 86     return FALSE; |  | 
| 87   } |  | 
| 88   if (bPrev) { |  | 
| 89     m_pCurIter->Release(); |  | 
| 90     m_pCurIter = m_pPreIter; |  | 
| 91     m_pCurIter->Next(TRUE); |  | 
| 92     m_pPreIter = pIter; |  | 
| 93   } else { |  | 
| 94     m_pPreIter->Release(); |  | 
| 95     m_pPreIter = m_pCurIter; |  | 
| 96     m_pPreIter->Next(); |  | 
| 97     m_pCurIter = pIter; |  | 
| 98   } |  | 
| 99   return TRUE; |  | 
| 100 } |  | 
| 101 void CFX_WordBreak::SetAt(int32_t nIndex) { |  | 
| 102   if (m_pPreIter) { |  | 
| 103     m_pPreIter->Release(); |  | 
| 104     m_pPreIter = NULL; |  | 
| 105   } |  | 
| 106   m_pCurIter->SetAt(nIndex); |  | 
| 107   FindNextBreakPos(m_pCurIter, TRUE, FALSE); |  | 
| 108   m_pPreIter = m_pCurIter; |  | 
| 109   m_pCurIter = m_pPreIter->Clone(); |  | 
| 110   FindNextBreakPos(m_pCurIter, FALSE, FALSE); |  | 
| 111 } |  | 
| 112 int32_t CFX_WordBreak::GetWordPos() const { |  | 
| 113   return m_pPreIter->GetAt(); |  | 
| 114 } |  | 
| 115 int32_t CFX_WordBreak::GetWordLength() const { |  | 
| 116   return m_pCurIter->GetAt() - m_pPreIter->GetAt() + 1; |  | 
| 117 } |  | 
| 118 void CFX_WordBreak::GetWord(CFX_WideString& wsWord) const { |  | 
| 119   int32_t nWordLength = GetWordLength(); |  | 
| 120   if (nWordLength <= 0) { |  | 
| 121     return; |  | 
| 122   } |  | 
| 123   FX_WCHAR* lpBuf = wsWord.GetBuffer(nWordLength); |  | 
| 124   IFX_CharIter* pTempIter = m_pPreIter->Clone(); |  | 
| 125   int32_t i = 0; |  | 
| 126   while (pTempIter->GetAt() <= m_pCurIter->GetAt()) { |  | 
| 127     lpBuf[i++] = pTempIter->GetChar(); |  | 
| 128     FX_BOOL bEnd = pTempIter->Next(); |  | 
| 129     if (!bEnd) { |  | 
| 130       break; |  | 
| 131     } |  | 
| 132   } |  | 
| 133   pTempIter->Release(); |  | 
| 134   wsWord.ReleaseBuffer(nWordLength); |  | 
| 135 } |  | 
| 136 FX_BOOL CFX_WordBreak::IsEOF(FX_BOOL bTail) const { |  | 
| 137   return m_pCurIter->IsEOF(bTail); |  | 
| 138 } |  | 
| 139 FX_BOOL CFX_WordBreak::FindNextBreakPos(IFX_CharIter* pIter, |  | 
| 140                                         FX_BOOL bPrev, |  | 
| 141                                         FX_BOOL bFromNext) { |  | 
| 142   FX_WordBreakProp ePreType = FX_WordBreakProp_None; |  | 
| 143   FX_WordBreakProp eCurType = FX_WordBreakProp_None; |  | 
| 144   FX_WordBreakProp eNextType = FX_WordBreakProp_None; |  | 
| 145   if (pIter->IsEOF(!bPrev)) { |  | 
| 146     return TRUE; |  | 
| 147   } |  | 
| 148   if (!(bFromNext || pIter->IsEOF(bPrev))) { |  | 
| 149     pIter->Next(!bPrev); |  | 
| 150     FX_WCHAR wcTemp = pIter->GetChar(); |  | 
| 151     ePreType = FX_GetWordBreakProperty(wcTemp); |  | 
| 152     pIter->Next(bPrev); |  | 
| 153   } |  | 
| 154   FX_WCHAR wcTemp = pIter->GetChar(); |  | 
| 155   eCurType = FX_GetWordBreakProperty(wcTemp); |  | 
| 156   FX_BOOL bFirst = TRUE; |  | 
| 157   do { |  | 
| 158     pIter->Next(bPrev); |  | 
| 159     FX_WCHAR wcTemp = pIter->GetChar(); |  | 
| 160     eNextType = FX_GetWordBreakProperty(wcTemp); |  | 
| 161     FX_WORD wBreak = |  | 
| 162         gs_FX_WordBreak_Table[eCurType] & ((FX_WORD)(1 << eNextType)); |  | 
| 163     if (wBreak) { |  | 
| 164       if (pIter->IsEOF(!bPrev)) { |  | 
| 165         pIter->Next(!bPrev); |  | 
| 166         return TRUE; |  | 
| 167       } |  | 
| 168       if (bFirst) { |  | 
| 169         int32_t nFlags = 0; |  | 
| 170         if (eCurType == FX_WordBreakProp_MidLetter) { |  | 
| 171           if (eNextType == FX_WordBreakProp_ALetter) { |  | 
| 172             nFlags = 1; |  | 
| 173           } |  | 
| 174         } else if (eCurType == FX_WordBreakProp_MidNum) { |  | 
| 175           if (eNextType == FX_WordBreakProp_Numberic) { |  | 
| 176             nFlags = 2; |  | 
| 177           } |  | 
| 178         } else if (eCurType == FX_WordBreakProp_MidNumLet) { |  | 
| 179           if (eNextType == FX_WordBreakProp_ALetter) { |  | 
| 180             nFlags = 1; |  | 
| 181           } else if (eNextType == FX_WordBreakProp_Numberic) { |  | 
| 182             nFlags = 2; |  | 
| 183           } |  | 
| 184         } |  | 
| 185         if (nFlags > 0) { |  | 
| 186           FXSYS_assert(nFlags <= 2); |  | 
| 187           if (!((nFlags == 1 && ePreType == FX_WordBreakProp_ALetter) || |  | 
| 188                 (nFlags == 2 && ePreType == FX_WordBreakProp_Numberic))) { |  | 
| 189             pIter->Next(!bPrev); |  | 
| 190             return TRUE; |  | 
| 191           } |  | 
| 192           pIter->Next(bPrev); |  | 
| 193           wBreak = FALSE; |  | 
| 194         } |  | 
| 195         bFirst = FALSE; |  | 
| 196       } |  | 
| 197       if (wBreak) { |  | 
| 198         int32_t nFlags = 0; |  | 
| 199         if (eNextType == FX_WordBreakProp_MidLetter) { |  | 
| 200           if (eCurType == FX_WordBreakProp_ALetter) { |  | 
| 201             nFlags = 1; |  | 
| 202           } |  | 
| 203         } else if (eNextType == FX_WordBreakProp_MidNum) { |  | 
| 204           if (eCurType == FX_WordBreakProp_Numberic) { |  | 
| 205             nFlags = 2; |  | 
| 206           } |  | 
| 207         } else if (eNextType == FX_WordBreakProp_MidNumLet) { |  | 
| 208           if (eCurType == FX_WordBreakProp_ALetter) { |  | 
| 209             nFlags = 1; |  | 
| 210           } else if (eCurType == FX_WordBreakProp_Numberic) { |  | 
| 211             nFlags = 2; |  | 
| 212           } |  | 
| 213         } |  | 
| 214         if (nFlags <= 0) { |  | 
| 215           pIter->Next(!bPrev); |  | 
| 216           return TRUE; |  | 
| 217         } |  | 
| 218         FXSYS_assert(nFlags <= 2); |  | 
| 219         pIter->Next(bPrev); |  | 
| 220         wcTemp = pIter->GetChar(); |  | 
| 221         eNextType = (FX_WordBreakProp)FX_GetWordBreakProperty(wcTemp); |  | 
| 222         if (!((nFlags == 1 && eNextType == FX_WordBreakProp_ALetter) || |  | 
| 223               (nFlags == 2 && eNextType == FX_WordBreakProp_Numberic))) { |  | 
| 224           pIter->Next(!bPrev); |  | 
| 225           pIter->Next(!bPrev); |  | 
| 226           return TRUE; |  | 
| 227         } |  | 
| 228       } |  | 
| 229     } |  | 
| 230     ePreType = eCurType; |  | 
| 231     eCurType = eNextType; |  | 
| 232     bFirst = FALSE; |  | 
| 233   } while (!pIter->IsEOF(!bPrev)); |  | 
| 234   return TRUE; |  | 
| 235 } |  | 
| 236 IFX_WordBreak* FX_WordBreak_Create() { |  | 
| 237   return new CFX_WordBreak; |  | 
| 238 } |  | 
| OLD | NEW | 
|---|