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/foxitlib.h"
8#include "fde_txtedtblock.h"
9#ifdef FDE_USEFORMATBLOCK
10#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
11#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
12#define FDE_TXTEDT_ZEROWIDTHSPACE 0x200B
13#define FDE_TXTEDT_ISINTEGER(a) ((a) >= L'0' && (a) <= L'9')
14#define FDE_TXTEDT_ISSIGN(a) (((a) == L'-') || ((a) == L'+'))
15CFDE_TxtEdtBlock::CFDE_TxtEdtBlock(CFDE_TxtEdtEngine* pEngine,
16                                   const CFX_WideString& wsBlock,
17                                   int32_t nPosition)
18    : m_pEngine(pEngine),
19      m_nDisplayLength(0),
20      m_nIndex(0),
21      m_nPosition(nPosition) {
22  const FX_WCHAR* lpBuf = const FX_WCHAR * (wsBlock);
23  int32_t nCount = wsBlock.GetLength();
24  int32_t i = 0;
25  CFX_WideString wsFix;
26  int32_t j = 0;
27  while (i < nCount) {
28    if (lpBuf[i] != L'%') {
29      wsFix += lpBuf[i];
30    } else {
31      i++;
32      if (i < nCount) {
33        if (lpBuf[i] == L'%') {
34          wsFix += lpBuf[i];
35        } else {
36          if (!wsFix.IsEmpty()) {
37            CFDE_TxtEdtField* pField = CFDE_TxtEdtField::Create(wsFix, j, this);
38            j++;
39            FXSYS_assert(pField);
40            m_FieldArr.Add(pField);
41            m_nDisplayLength += pField->GetDisplayLength();
42            wsFix.Empty();
43          }
44          int32_t nPos = i - 1;
45          while (lpBuf[i++] != L')')
46            ;
47          i++;
48          CFX_WideStringC wsField(lpBuf + nPos, i - nPos);
49          CFDE_TxtEdtField* pField = CFDE_TxtEdtField::Create(wsField, j, this);
50          j++;
51          FXSYS_assert(pField);
52          m_FieldArr.Add(pField);
53          m_EditFieldArr.Add(pField);
54          m_nDisplayLength += pField->GetDisplayLength();
55          i--;
56        }
57      }
58    }
59    i++;
60  }
61  if (!wsFix.IsEmpty()) {
62    CFDE_TxtEdtField* pField = CFDE_TxtEdtField::Create(wsFix, j, this);
63    FXSYS_assert(pField);
64    m_FieldArr.Add(pField);
65    m_nDisplayLength += pField->GetDisplayLength();
66  }
67}
68CFDE_TxtEdtBlock::~CFDE_TxtEdtBlock() {
69  int32_t nCount = m_FieldArr.GetSize();
70  for (int32_t i = 0; i < nCount; i++) {
71    CFDE_TxtEdtField* pField = m_FieldArr[i];
72    pField->Release();
73  }
74  m_FieldArr.RemoveAll();
75}
76void CFDE_TxtEdtBlock::GetDisplayText(CFX_WideString& wsDisplay) {
77  int32_t nCount = m_FieldArr.GetSize();
78  for (int32_t i = 0; i < nCount; i++) {
79    CFDE_TxtEdtField* pField = m_FieldArr[i];
80    CFX_WideString wsTemp;
81    pField->GetDisplayText(wsTemp);
82    wsDisplay += wsTemp;
83  }
84}
85int32_t CFDE_TxtEdtBlock::GetLength() const {
86  int32_t nDisplayLength = 0;
87  int32_t nCount = m_FieldArr.GetSize();
88  for (int32_t i = 0; i < nCount; i++) {
89    CFDE_TxtEdtField* pField = m_FieldArr[i];
90    nDisplayLength += pField->GetDisplayLength();
91  }
92  return nDisplayLength;
93}
94void CFDE_TxtEdtBlock::GetBlockText(CFX_WideString& wsBlock) {
95  int32_t nCount = m_FieldArr.GetSize();
96  for (int32_t i = 0; i < nCount; i++) {
97    CFDE_TxtEdtField* pField = m_FieldArr[i];
98    CFX_WideString wsTemp;
99    pField->GetFieldText(wsTemp);
100    wsBlock += wsTemp;
101  }
102}
103int32_t CFDE_TxtEdtBlock::CountField() const {
104  return m_EditFieldArr.GetSize();
105}
106void CFDE_TxtEdtBlock::GetFieldText(int32_t nIndex, CFX_WideString& wsField) {
107  CFDE_TxtEdtField* pField = m_EditFieldArr[nIndex];
108  pField->GetFieldText(wsField);
109}
110int32_t CFDE_TxtEdtBlock::GetFieldTextLength() const {
111  int32_t nTotalLength = 0;
112  int32_t nCount = m_EditFieldArr.GetSize();
113  for (int32_t i = 0; i < nCount; i++) {
114    CFDE_TxtEdtField* pField = m_EditFieldArr[i];
115    nTotalLength = pField->GetFieldTextLength();
116  }
117  return nTotalLength;
118}
119int32_t CFDE_TxtEdtBlock::GetPos() const {
120  return m_nPosition;
121}
122void CFDE_TxtEdtBlock::GetRealText(CFX_WideString& wsText) const {
123  int32_t nCount = m_FieldArr.GetSize();
124  for (int32_t i = 0; i < nCount; i++) {
125    CFDE_TxtEdtField* pField = m_FieldArr[i];
126    CFX_WideString wsTemp;
127    pField->GetFieldText(wsTemp);
128    wsText += wsTemp;
129  }
130}
131void CFDE_TxtEdtBlock::Backup() {
132  int32_t nCount = m_EditFieldArr.GetSize();
133  for (int32_t i = 0; i < nCount; i++) {
134    m_EditFieldArr[i]->Backup();
135  }
136}
137void CFDE_TxtEdtBlock::Restore() {
138  int32_t nCount = m_EditFieldArr.GetSize();
139  for (int32_t i = 0; i < nCount; i++) {
140    m_EditFieldArr[i]->Restore();
141  }
142}
143CFDE_TxtEdtFieldFormatParser::CFDE_TxtEdtFieldFormatParser() {}
144CFDE_TxtEdtFieldFormatParser::~CFDE_TxtEdtFieldFormatParser() {
145  FDE_LPTXTEDTFORMATITEM lpItem = NULL;
146  int32_t nCount = m_ItemArr.GetSize();
147  for (int32_t i = 0; i < nCount; i++) {
148    lpItem = m_ItemArr[i];
149    delete lpItem;
150  }
151  m_ItemArr.RemoveAll();
152}
153FX_BOOL CFDE_TxtEdtFieldFormatParser::Parse(const CFX_WideString& wsFormat) {
154  m_wsFormat = wsFormat;
155  const FX_WCHAR* pBuf = const FX_WCHAR * (m_wsFormat);
156  int32_t nCount = m_wsFormat.GetLength();
157  nCount -= 2;
158  int32_t i = 0;
159  for (; i < nCount; i++) {
160    FX_WCHAR wChar = pBuf[i];
161    if (wChar == L'(') {
162      break;
163    }
164  }
165  i++;
166  FDE_TXTEDTFORMATITEM FormatItem;
167  for (; i < nCount; i++) {
168    while (pBuf[i] == L' ') {
169      i++;
170    }
171    FormatItem.nKeyStart = i;
172    while (pBuf[i] != L':') {
173      i++;
174    }
175    FormatItem.nKeyCount = i - FormatItem.nKeyStart;
176    i++;
177    FormatItem.nValStart = i;
178    while (pBuf[i] != L';' && i < nCount) {
179      i++;
180    }
181    FormatItem.nValCount = i - FormatItem.nValStart;
182    FDE_LPTXTEDTFORMATITEM pFormatItem = new FDE_TXTEDTFORMATITEM;
183    FXSYS_memcpy(pFormatItem, &FormatItem, sizeof(FDE_TXTEDTFORMATITEM));
184    m_ItemArr.Add(pFormatItem);
185  }
186  return TRUE;
187}
188int32_t CFDE_TxtEdtFieldFormatParser::CountItems() const {
189  return m_ItemArr.GetSize();
190}
191void CFDE_TxtEdtFieldFormatParser::GetItem(int32_t nIndex,
192                                           CFX_WideString& wsKey,
193                                           CFX_WideString& wsValue) const {
194  FDE_LPTXTEDTFORMATITEM lpItem = m_ItemArr[nIndex];
195  const FX_WCHAR* lpSrcBuf = const FX_WCHAR * (m_wsFormat);
196  FX_WCHAR* lpDstBuf = wsKey.GetBuffer(lpItem->nKeyCount);
197  FXSYS_memcpy(lpDstBuf, lpSrcBuf + lpItem->nKeyStart,
198               lpItem->nKeyCount * sizeof(FX_WCHAR));
199  wsKey.ReleaseBuffer(lpItem->nKeyCount);
200  lpDstBuf = wsValue.GetBuffer(lpItem->nValCount);
201  FXSYS_memcpy(lpDstBuf, lpSrcBuf + lpItem->nValStart,
202               lpItem->nValCount * sizeof(FX_WCHAR));
203  wsValue.ReleaseBuffer(lpItem->nValCount);
204}
205CFDE_TxtEdtField* CFDE_TxtEdtField::Create(const CFX_WideString& wsField,
206                                           int32_t nIndex,
207                                           CFDE_TxtEdtBlock* pBlock) {
208  if (wsField[0] != L'%' || (wsField[0] == L'%' && wsField[1] == L'%')) {
209    return new CFDE_TxtEdtField_Fixed(wsField, nIndex, pBlock);
210  }
211  FX_WCHAR wcType = wsField[wsField.GetLength() - 1];
212  switch (wcType) {
213    case L'd':
214      return new CFDE_TxtEdtField_Integer(wsField, nIndex, pBlock);
215    case L'f':
216      return new CFDE_TxtEdtField_Float(wsField, nIndex, pBlock);
217    case L's':
218      return new CFDE_TxtEdtField_String(wsField, nIndex, pBlock);
219    case L'p':
220      return new CFDE_TxtEdtField_Password(wsField, nIndex, pBlock);
221    default:
222      break;
223  }
224  return NULL;
225}
226void CFDE_TxtEdtField::Release() {
227  delete this;
228}
229CFDE_TxtEdtField::CFDE_TxtEdtField(int32_t nIndex, CFDE_TxtEdtBlock* pBlock)
230    : m_nLength(-1),
231      m_wcFill(L' '),
232      m_bReserveSpace(FALSE),
233      m_bLeftAlignment(TRUE),
234      m_nIndex(nIndex),
235      m_pBlock(pBlock) {
236  FXSYS_assert(pBlock);
237}
238int32_t CFDE_TxtEdtField::Insert(int32_t nIndex,
239                                 const CFX_WideString& wsIns,
240                                 int32_t& nCaret,
241                                 FX_BOOL& bBefore) {
242  int32_t nFieldLength = m_wsField.GetLength();
243  int32_t nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
244  if (m_bReserveSpace && !m_bLeftAlignment) {
245    nInnerIndex -= (m_nLength - nFieldLength);
246  }
247  FXSYS_assert(nInnerIndex >= 0 && nInnerIndex <= nFieldLength);
248  CFX_WideString wsTemp = m_wsField;
249  int32_t nInsLength = wsIns.GetLength();
250  for (int32_t i = 0; i < nInsLength; i++, nInnerIndex++) {
251    wsTemp.Insert(nInnerIndex, wsIns[i]);
252  }
253  int32_t nRet = Validate(wsTemp);
254  switch (nRet) {
255    case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
256      return FDE_FORMAT_FIELD_INSERT_RET_F_FULL;
257    case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
258      return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
259    case FDE_FORMAT_FIELD_VALIDATE_S:
260    default:
261      break;
262  }
263  m_wsField = wsTemp;
264  nCaret = nIndex +
265           ((m_bReserveSpace && !m_bLeftAlignment) ? -nInsLength : nInsLength);
266  bBefore = TRUE;
267  return (nFieldLength + nInsLength < m_nLength)
268             ? FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL
269             : FDE_FORMAT_FIELD_INSERT_RET_S_FULL;
270}
271int32_t CFDE_TxtEdtField::Delete(int32_t nIndex,
272                                 int32_t nCount,
273                                 CFX_WideString& wsDel,
274                                 int32_t& nCaret,
275                                 FX_BOOL& bBefore) {
276  int32_t nFieldLength = m_wsField.GetLength();
277  int32_t nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
278  if (m_bReserveSpace && !m_bLeftAlignment) {
279    nInnerIndex -= (m_nLength - nFieldLength);
280  }
281  if (nInnerIndex < 0 || (nInnerIndex + nCount) > nFieldLength) {
282    return FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY;
283  }
284  CFX_WideString wsTemp = m_wsField;
285  wsTemp.Delete(nInnerIndex, nCount);
286  int32_t nRet = Validate(wsTemp);
287  switch (nRet) {
288    case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
289      return FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY;
290    case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
291      return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
292    case FDE_FORMAT_FIELD_VALIDATE_S:
293    default:
294      break;
295  }
296  FX_WCHAR* lpBuf = wsDel.GetBuffer(nCount);
297  FXSYS_memcpy(lpBuf, const FX_WCHAR*(m_wsField) + nInnerIndex,
298               nCount * sizeof(FX_WCHAR));
299  wsDel.ReleaseBuffer(nCount);
300  m_wsField = wsTemp;
301  nCaret = nIndex + (m_bReserveSpace && !m_bLeftAlignment) ? nCount : 0;
302  bBefore = TRUE;
303  return FDE_FORMAT_FIELD_DELETE_RET_S;
304}
305int32_t CFDE_TxtEdtField::Replace(int32_t nIndex,
306                                  int32_t nCount,
307                                  const CFX_WideString& wsIns,
308                                  CFX_WideString& wsDel,
309                                  int32_t& nCaret,
310                                  FX_BOOL& bBefore) {
311  int32_t nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
312  int32_t nInsLength = wsIns.GetLength();
313  int32_t nFieldLength = m_wsField.GetLength();
314  CFX_WideString wsTemp = m_wsField;
315  if (m_bReserveSpace && !m_bLeftAlignment) {
316    nInnerIndex -= (m_nLength - nFieldLength);
317  }
318  FXSYS_assert(nInnerIndex >= 0 && nInnerIndex <= nFieldLength);
319  if (nInnerIndex + nCount > nFieldLength) {
320    return FALSE;
321  }
322  wsTemp.Delete(nInnerIndex, nCount);
323  int32_t nInnerIndexBK = nInnerIndex;
324  for (int32_t i = 0; i < nInsLength; i++, nInnerIndex++) {
325    wsTemp.Insert(nInnerIndex, wsIns[i]);
326  }
327  int32_t nRet = Validate(wsTemp);
328  switch (nRet) {
329    case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
330      return FDE_FORMAT_FIELD_INSERT_RET_F_FULL;
331    case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
332      return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
333    default:
334      break;
335  }
336  FX_WCHAR* lpBuffer = wsDel.GetBuffer(nCount);
337  const FX_WCHAR* lpSrcBuf = const FX_WCHAR * (m_wsField);
338  FXSYS_memcpy(lpBuffer, lpSrcBuf + nInnerIndexBK, nCount * sizeof(FX_WCHAR));
339  wsDel.ReleaseBuffer(nCount);
340  m_wsField = wsTemp;
341  nCaret =
342      nIndex + ((m_bReserveSpace && !m_bLeftAlignment) ? (nCount - nInsLength)
343                                                       : (nInsLength));
344  return FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL;
345}
346void CFDE_TxtEdtField::GetDisplayText(CFX_WideString& wsDisplay) {
347  CFX_WideString wsField;
348  GetNormalizedFieldText(wsField);
349  int32_t nLength = wsField.GetLength() + FDE_FORMAT_EDIT_FIELD_HADERSIZE +
350                    FDE_FORMAT_EDIT_FIELD_TAILSIZE;
351  FX_WCHAR* lpBuffer = wsDisplay.GetBuffer(nLength);
352  lpBuffer[0] = FDE_TXTEDT_FORMATBLOCK_BGN;
353  lpBuffer[nLength - 1] = FDE_TXTEDT_FORMATBLOCK_END;
354  FX_DWORD nAddress = (FX_DWORD) this;
355  FXSYS_memcpy(lpBuffer + 1, &nAddress, sizeof(FX_DWORD));
356  FXSYS_memcpy(lpBuffer + 3, const FX_WCHAR*(wsField),
357               (nLength - 4) * sizeof(FX_WCHAR));
358  wsDisplay.ReleaseBuffer(nLength);
359}
360int32_t CFDE_TxtEdtField::GetDisplayLength() {
361  return (m_bReserveSpace ? m_nLength : m_wsField.GetLength()) +
362         FDE_FORMAT_EDIT_FIELD_HADERSIZE + FDE_FORMAT_EDIT_FIELD_TAILSIZE;
363}
364void CFDE_TxtEdtField::GetFieldText(CFX_WideString& wsField) {
365  wsField = m_wsField;
366}
367int32_t CFDE_TxtEdtField::GetFieldTextLength() const {
368  return m_wsField.GetLength();
369}
370int32_t CFDE_TxtEdtField::GetRealIndex(int32_t nIndex) const {
371  int32_t nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
372  if (nInnerIndex < 0) {
373    return 0;
374  }
375  int32_t nFieldLength = m_wsField.GetLength();
376  if (m_bReserveSpace && !m_bLeftAlignment) {
377    nInnerIndex -= (m_nLength - nFieldLength);
378  }
379  if (nInnerIndex < 0) {
380    return 0;
381  }
382  if (nInnerIndex >= nFieldLength) {
383    return nFieldLength;
384  }
385  return nInnerIndex + 1;
386}
387int32_t CFDE_TxtEdtField::NormalizeCaretPos(
388    int32_t nIndex,
389    FDE_FORMAT_CARET_DIRECTION eDirection) const {
390  nIndex -= FDE_FORMAT_EDIT_FIELD_HADERSIZE;
391  int32_t nLength = m_wsField.GetLength();
392  if (m_bReserveSpace) {
393    int32_t nFieldLength = m_wsField.GetLength();
394    if (m_bLeftAlignment) {
395      if (nIndex > nFieldLength) {
396        if (eDirection == FDE_FORMAT_CARET_FORWARD) {
397          return -1;
398        }
399        nIndex = nFieldLength;
400      }
401    } else {
402      int32_t nReserveLength = m_nLength - nFieldLength;
403      if (nIndex < nReserveLength) {
404        if (eDirection == FDE_FORMAT_CARET_BACKWARD) {
405          return -2;
406        }
407        nIndex = nReserveLength;
408      }
409    }
410  }
411  return nIndex + FDE_FORMAT_EDIT_FIELD_HADERSIZE;
412}
413FX_BOOL CFDE_TxtEdtField::GetEditableRange(int32_t& nBgn, int32_t& nEnd) const {
414  if (m_bReserveSpace && !m_bLeftAlignment) {
415    nEnd = FDE_FORMAT_EDIT_FIELD_HADERSIZE + m_nLength;
416    nBgn = nEnd - m_wsField.GetLength();
417  } else {
418    nBgn = FDE_FORMAT_EDIT_FIELD_HADERSIZE;
419    nEnd = nBgn + m_wsField.GetLength();
420  }
421  return TRUE;
422}
423void CFDE_TxtEdtField::Backup() {
424  m_wsBackup = m_wsField;
425}
426void CFDE_TxtEdtField::Restore() {
427  m_wsField = m_wsBackup;
428}
429int32_t CFDE_TxtEdtField::Validate(const CFX_WideString& wsText) const {
430  if (m_nLength < 0) {
431    return FDE_FORMAT_FIELD_DELETE_RET_S;
432  }
433  return wsText.GetLength() <= m_nLength ? FDE_FORMAT_FIELD_VALIDATE_S
434                                         : FDE_FORMAT_FIELD_VALIDATE_F_FULL;
435}
436void CFDE_TxtEdtField::GetNormalizedFieldText(CFX_WideString& wsField) const {
437  wsField = m_wsField;
438  if (m_nLength == -1) {
439    return;
440  }
441  if (m_bReserveSpace) {
442    int32_t nField = wsField.GetLength();
443    int32_t nFill = m_nLength - nField;
444    if (m_bLeftAlignment) {
445      while (nFill--) {
446        wsField.Insert(nField++, m_wcFill);
447      }
448    } else {
449      while (nFill--) {
450        wsField.Insert(0, m_wcFill);
451      }
452    }
453  }
454}
455CFDE_TxtEdtField_Integer::CFDE_TxtEdtField_Integer(
456    const CFX_WideString& wsField,
457    int32_t nIndex,
458    CFDE_TxtEdtBlock* pBlock)
459    : m_bSign(FALSE), CFDE_TxtEdtField(nIndex, pBlock) {
460  CFDE_TxtEdtFieldFormatParser FormatParser;
461  FormatParser.Parse(wsField);
462  int32_t nCount = FormatParser.CountItems();
463  CFX_WideString wskey;
464  CFX_WideString wsVal;
465  for (int32_t i = 0; i < nCount; i++) {
466    FormatParser.GetItem(i, wskey, wsVal);
467    if (wskey.Equal(L"Length")) {
468      m_nLength = wsVal.GetInteger();
469    } else if (wskey.Equal(L"Sign")) {
470      m_bSign = wsVal.GetInteger() != 0;
471    } else if (wskey.Equal(L"FillChar")) {
472      m_wcFill = wsVal[0];
473    } else {
474      FXSYS_assert(0);
475    }
476    wskey.Empty();
477    wsVal.Empty();
478  }
479  if (m_nLength == -1) {
480    m_bReserveSpace = FALSE;
481  }
482}
483int32_t CFDE_TxtEdtField_Integer::Validate(const CFX_WideString& wsText) const {
484  int32_t i = 0;
485  if (m_bSign) {
486    FX_WCHAR wcTemp = wsText[0];
487    if (FDE_TXTEDT_ISSIGN(wcTemp)) {
488      i++;
489    }
490  }
491  int32_t nLength = wsText.GetLength();
492  if (m_nLength > 0) {
493    if (nLength - i > (m_nLength - (m_bSign ? 1 : 0))) {
494      return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
495    }
496  }
497  for (; i < nLength; i++) {
498    FX_WCHAR wcTemp = wsText[i];
499    if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
500      return FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE;
501    }
502  }
503  return FDE_FORMAT_FIELD_VALIDATE_S;
504}
505CFDE_TxtEdtField_Float::CFDE_TxtEdtField_Float(const CFX_WideString& wsField,
506                                               int32_t nIndex,
507                                               CFDE_TxtEdtBlock* pBlock)
508    : CFDE_TxtEdtField(nIndex, pBlock),
509      m_bSigned(FALSE),
510      m_nIntPartlength(-1),
511      m_nDecPartLength(-1) {
512  CFDE_TxtEdtFieldFormatParser FormatParser;
513  FormatParser.Parse(wsField);
514  int32_t nCount = FormatParser.CountItems();
515  CFX_WideString wskey;
516  CFX_WideString wsVal;
517  for (int32_t i = 0; i < nCount; i++) {
518    FormatParser.GetItem(i, wskey, wsVal);
519    if (wskey.Equal(L"DecLength")) {
520      m_nDecPartLength = wsVal.GetInteger();
521    } else if (wskey.Equal(L"IntLength")) {
522      m_nIntPartlength = wsVal.GetInteger();
523    } else if (wskey.Equal(L"Sign")) {
524      m_bSigned = wsVal.GetInteger() != 0;
525    } else if (wskey.Equal(L"FillChar")) {
526      m_wcFill = wsVal[0];
527    } else {
528      FXSYS_assert(0);
529    }
530    if (m_nIntPartlength == -1 || m_nDecPartLength == -1) {
531      m_nLength = -1;
532    } else {
533      m_nLength = m_nIntPartlength + m_nDecPartLength + 1 + (m_bSigned ? 1 : 0);
534    }
535    m_bReserveSpace = TRUE;
536    wskey.Empty();
537    wsVal.Empty();
538  }
539}
540int32_t CFDE_TxtEdtField_Float::Validate(const CFX_WideString& wsText) const {
541  int32_t nLength = wsText.GetLength();
542  if (m_nLength != -1 && (nLength > m_nLength)) {
543    return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
544  }
545  const FX_WCHAR* lpBuf = const FX_WCHAR * (wsText);
546  int32_t i = 0;
547  if (m_bSigned) {
548    FX_WCHAR wcTemp = lpBuf[0];
549    if (FDE_TXTEDT_ISSIGN(wcTemp)) {
550      i++;
551    }
552  }
553  int32_t nIntPart = 0;
554  int32_t nPoint = 0;
555  for (; i < nLength; i++) {
556    FX_WCHAR wcTemp = lpBuf[i];
557    if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
558      if (wcTemp != L'.') {
559        return FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE;
560      }
561      nPoint = 1;
562      break;
563    }
564    nIntPart++;
565  }
566  if (m_nIntPartlength != -1 && (nIntPart > m_nIntPartlength)) {
567    return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
568  }
569  if (m_nDecPartLength != -1 &&
570      (nLength - nIntPart - nPoint > m_nDecPartLength)) {
571    return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
572  }
573  i++;
574  for (; i < nLength; i++) {
575    FX_WCHAR wcTemp = lpBuf[i];
576    if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
577      return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
578    }
579  }
580  return FDE_FORMAT_FIELD_VALIDATE_S;
581}
582CFDE_TxtEdtField_Password::CFDE_TxtEdtField_Password(
583    const CFX_WideString& wsField,
584    int32_t nIndex,
585    CFDE_TxtEdtBlock* pBlock)
586    : CFDE_TxtEdtField(nIndex, pBlock), m_wcAlias(L'*') {
587  CFDE_TxtEdtFieldFormatParser FormatParser;
588  FormatParser.Parse(wsField);
589  int32_t nCount = FormatParser.CountItems();
590  CFX_WideString wskey;
591  CFX_WideString wsVal;
592  for (int32_t i = 0; i < nCount; i++) {
593    FormatParser.GetItem(i, wskey, wsVal);
594    if (wskey.Equal(L"Length")) {
595      m_nLength = wsVal.GetInteger();
596    } else if (wskey.Equal(L"AliasChar")) {
597      m_wcAlias = wsVal[0];
598    } else {
599      FXSYS_assert(0);
600    }
601    wskey.Empty();
602    wsVal.Empty();
603  }
604  if (m_nLength == -1) {
605    m_bReserveSpace = FALSE;
606  }
607}
608void CFDE_TxtEdtField_Password::GetNormalizedFieldText(
609    CFX_WideString& wsField) const {
610  int32_t nFiledLength = m_wsField.GetLength();
611  int32_t nLength = m_bReserveSpace ? m_nLength : nFiledLength;
612  FX_WCHAR* lpBuf = wsField.GetBuffer(nLength);
613  int32_t nSpaceLength = nLength - nFiledLength;
614  int32_t nFirstPart = m_bLeftAlignment ? nFiledLength : nSpaceLength;
615  FX_WCHAR wFirstChar = m_bLeftAlignment ? m_wcAlias : L' ';
616  FX_WCHAR wSecondChar = m_bLeftAlignment ? L' ' : m_wcAlias;
617  int32_t i = 0;
618  for (; i < nFirstPart; i++) {
619    lpBuf[i] = wFirstChar;
620  }
621  for (; i < nLength; i++) {
622    lpBuf[i] = wSecondChar;
623  }
624  wsField.ReleaseBuffer(nLength);
625}
626CFDE_TxtEdtField_String::CFDE_TxtEdtField_String(const CFX_WideString& wsField,
627                                                 int32_t nIndex,
628                                                 CFDE_TxtEdtBlock* pBlock)
629    : CFDE_TxtEdtField(nIndex, pBlock) {
630  CFDE_TxtEdtFieldFormatParser FormatParser;
631  FormatParser.Parse(wsField);
632  int32_t nCount = FormatParser.CountItems();
633  CFX_WideString wskey;
634  CFX_WideString wsVal;
635  for (int32_t i = 0; i < nCount; i++) {
636    FormatParser.GetItem(i, wskey, wsVal);
637    if (wskey.Equal(L"Length")) {
638      m_nLength = wsVal.GetInteger();
639    } else {
640      FXSYS_assert(0);
641    }
642    wskey.Empty();
643    wsVal.Empty();
644  }
645}
646CFDE_TxtEdtField_Fixed::CFDE_TxtEdtField_Fixed(const CFX_WideString& wsField,
647                                               int32_t nIndex,
648                                               CFDE_TxtEdtBlock* pBlock)
649    : CFDE_TxtEdtField(nIndex, pBlock) {
650  m_wsField = wsField;
651  m_nLength = wsField.GetLength();
652}
653void CFDE_TxtEdtField_Fixed::GetDisplayText(CFX_WideString& wsDisplay) {
654  int32_t nLength = m_wsField.GetLength() + FDE_FORMAT_EDIT_FIELD_HADERSIZE +
655                    FDE_FORMAT_EDIT_FIELD_TAILSIZE;
656  FX_WCHAR* lpBuffer = wsDisplay.GetBuffer(nLength);
657  lpBuffer[0] = FDE_TXTEDT_FORMATBLOCK_BGN;
658  lpBuffer[nLength - 1] = FDE_TXTEDT_FORMATBLOCK_END;
659  FX_DWORD nAddress = (FX_DWORD) this;
660  FXSYS_memcpy(lpBuffer + 1, &nAddress, sizeof(FX_DWORD));
661  FXSYS_memcpy(lpBuffer + 3, const FX_WCHAR*(m_wsField),
662               (nLength - 4) * sizeof(FX_WCHAR));
663  wsDisplay.ReleaseBuffer(nLength);
664}
665int32_t CFDE_TxtEdtField_Fixed::NormalizeCaretPos(
666    int32_t nIndex,
667    FDE_FORMAT_CARET_DIRECTION eDirection) const {
668  FXSYS_assert(nIndex >= 0 && nIndex <= m_nLength);
669  if (eDirection == FDE_FORMAT_CARET_MIDDLE) {
670    return (nIndex > m_wsField.GetLength() / 2) ? -1 : -2;
671  }
672  return eDirection == FDE_FORMAT_CARET_BACKWARD ? -2 : -1;
673}
674#endif
675