summaryrefslogtreecommitdiff
path: root/xfa/src/fgas/src
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fgas/src')
-rw-r--r--xfa/src/fgas/src/crt/fx_algorithm.cpp598
-rw-r--r--xfa/src/fgas/src/crt/fx_codepage.cpp680
-rw-r--r--xfa/src/fgas/src/crt/fx_encode.cpp384
-rw-r--r--xfa/src/fgas/src/crt/fx_memory.cpp648
-rw-r--r--xfa/src/fgas/src/crt/fx_memory.h270
-rw-r--r--xfa/src/fgas/src/crt/fx_stream.cpp2714
-rw-r--r--xfa/src/fgas/src/crt/fx_stream.h622
-rw-r--r--xfa/src/fgas/src/crt/fx_system.cpp458
-rw-r--r--xfa/src/fgas/src/crt/fx_utils.cpp864
-rw-r--r--xfa/src/fgas/src/crt/fx_utils.h72
-rw-r--r--xfa/src/fgas/src/fgas_base.h28
-rw-r--r--xfa/src/fgas/src/font/fx_fontutils.cpp298
-rw-r--r--xfa/src/fgas/src/font/fx_fontutils.h42
-rw-r--r--xfa/src/fgas/src/font/fx_gdifont.cpp1078
-rw-r--r--xfa/src/fgas/src/font/fx_gdifont.h212
-rw-r--r--xfa/src/fgas/src/font/fx_gefont.cpp1176
-rw-r--r--xfa/src/fgas/src/font/fx_gefont.h180
-rw-r--r--xfa/src/fgas/src/font/fx_stdfontmgr.cpp3054
-rw-r--r--xfa/src/fgas/src/font/fx_stdfontmgr.h468
-rw-r--r--xfa/src/fgas/src/layout/fx_linebreak.cpp636
-rw-r--r--xfa/src/fgas/src/layout/fx_rtfbreak.cpp3050
-rw-r--r--xfa/src/fgas/src/layout/fx_rtfbreak.h348
-rw-r--r--xfa/src/fgas/src/layout/fx_textbreak.cpp3322
-rw-r--r--xfa/src/fgas/src/layout/fx_textbreak.h342
-rw-r--r--xfa/src/fgas/src/layout/fx_unicode.cpp234
-rw-r--r--xfa/src/fgas/src/layout/fx_unicode.h30
-rw-r--r--xfa/src/fgas/src/localization/fx_datetime.cpp1106
-rw-r--r--xfa/src/fgas/src/localization/fx_locale.cpp10254
-rw-r--r--xfa/src/fgas/src/localization/fx_localeimp.h232
-rw-r--r--xfa/src/fgas/src/localization/fx_localemgr.cpp194
-rw-r--r--xfa/src/fgas/src/localization/fx_localemgr.h48
-rw-r--r--xfa/src/fgas/src/xml/fx_sax_imp.cpp1378
-rw-r--r--xfa/src/fgas/src/xml/fx_sax_imp.h268
33 files changed, 17644 insertions, 17644 deletions
diff --git a/xfa/src/fgas/src/crt/fx_algorithm.cpp b/xfa/src/fgas/src/crt/fx_algorithm.cpp
index dc848458cf..196cb87b21 100644
--- a/xfa/src/fgas/src/crt/fx_algorithm.cpp
+++ b/xfa/src/fgas/src/crt/fx_algorithm.cpp
@@ -1,299 +1,299 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-const static FX_CHAR g_FXBase64EncoderMap[64] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
-};
-typedef struct _FX_BASE64DATA {
- FX_DWORD data1 : 2;
- FX_DWORD data2 : 6;
- FX_DWORD data3 : 4;
- FX_DWORD data4 : 4;
- FX_DWORD data5 : 6;
- FX_DWORD data6 : 2;
- FX_DWORD data7 : 8;
-} FX_BASE64DATA, *FX_LPBASE64ENCODEDATA;
-typedef FX_BASE64DATA const* FX_LPCBASE64DATA;
-static void FX_Base64EncodePiece(const FX_BASE64DATA& src,
- int32_t iBytes,
- FX_CHAR dst[4]) {
- dst[0] = g_FXBase64EncoderMap[src.data2];
- FX_DWORD b = src.data1 << 4;
- if (iBytes > 1) {
- b |= src.data4;
- }
- dst[1] = g_FXBase64EncoderMap[b];
- if (iBytes > 1) {
- b = src.data3 << 2;
- if (iBytes > 2) {
- b |= src.data6;
- }
- dst[2] = g_FXBase64EncoderMap[b];
- if (iBytes > 2) {
- dst[3] = g_FXBase64EncoderMap[src.data5];
- } else {
- dst[3] = '=';
- }
- } else {
- dst[2] = dst[3] = '=';
- }
-}
-int32_t FX_Base64EncodeA(const uint8_t* pSrc, int32_t iSrcLen, FX_CHAR* pDst) {
- FXSYS_assert(pSrc != NULL);
- if (iSrcLen < 1) {
- return 0;
- }
- if (pDst == NULL) {
- int32_t iDstLen = iSrcLen / 3 * 4;
- if ((iSrcLen % 3) != 0) {
- iDstLen += 4;
- }
- return iDstLen;
- }
- FX_BASE64DATA srcData;
- int32_t iBytes = 3;
- FX_CHAR* pDstEnd = pDst;
- while (iSrcLen > 0) {
- if (iSrcLen > 2) {
- ((uint8_t*)&srcData)[0] = *pSrc++;
- ((uint8_t*)&srcData)[1] = *pSrc++;
- ((uint8_t*)&srcData)[2] = *pSrc++;
- iSrcLen -= 3;
- } else {
- *((FX_DWORD*)&srcData) = 0;
- ((uint8_t*)&srcData)[0] = *pSrc++;
- if (iSrcLen > 1) {
- ((uint8_t*)&srcData)[1] = *pSrc++;
- }
- iBytes = iSrcLen;
- iSrcLen = 0;
- }
- FX_Base64EncodePiece(srcData, iBytes, pDstEnd);
- pDstEnd += 4;
- }
- return pDstEnd - pDst;
-}
-const static uint8_t g_FXBase64DecoderMap[256] = {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
- 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
- 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
- 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
- 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
- 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
-};
-static void FX_Base64DecodePiece(const FX_CHAR src[4],
- int32_t iChars,
- FX_BASE64DATA& dst,
- int32_t& iBytes) {
- FXSYS_assert(iChars > 0 && iChars < 5);
- iBytes = 1;
- dst.data2 = g_FXBase64DecoderMap[(uint8_t)src[0]];
- if (iChars > 1) {
- uint8_t b = g_FXBase64DecoderMap[(uint8_t)src[1]];
- dst.data1 = b >> 4;
- dst.data4 = b;
- if (iChars > 2) {
- iBytes = 2;
- b = g_FXBase64DecoderMap[(uint8_t)src[2]];
- dst.data3 = b >> 2;
- dst.data6 = b;
- if (iChars > 3) {
- iBytes = 3;
- dst.data5 = g_FXBase64DecoderMap[(uint8_t)src[3]];
- } else {
- dst.data5 = 0;
- }
- } else {
- dst.data3 = 0;
- }
- } else {
- dst.data1 = 0;
- }
-}
-int32_t FX_Base64DecodeA(const FX_CHAR* pSrc, int32_t iSrcLen, uint8_t* pDst) {
- FXSYS_assert(pSrc != NULL);
- if (iSrcLen < 1) {
- return 0;
- }
- while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
- iSrcLen--;
- }
- if (iSrcLen < 1) {
- return 0;
- }
- if (pDst == NULL) {
- int32_t iDstLen = iSrcLen / 4 * 3;
- iSrcLen %= 4;
- if (iSrcLen == 1) {
- iDstLen += 1;
- } else if (iSrcLen == 2) {
- iDstLen += 1;
- } else if (iSrcLen == 3) {
- iDstLen += 2;
- }
- return iDstLen;
- }
- FX_CHAR srcData[4];
- FX_BASE64DATA dstData;
- int32_t iChars = 4, iBytes;
- uint8_t* pDstEnd = pDst;
- while (iSrcLen > 0) {
- if (iSrcLen > 3) {
- *((FX_DWORD*)srcData) = *((FX_DWORD*)pSrc);
- pSrc += 4;
- iSrcLen -= 4;
- } else {
- *((FX_DWORD*)&dstData) = 0;
- *((FX_DWORD*)srcData) = 0;
- srcData[0] = *pSrc++;
- if (iSrcLen > 1) {
- srcData[1] = *pSrc++;
- }
- if (iSrcLen > 2) {
- srcData[2] = *pSrc++;
- }
- iChars = iSrcLen;
- iSrcLen = 0;
- }
- FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
- *pDstEnd++ = ((uint8_t*)&dstData)[0];
- if (iBytes > 1) {
- *pDstEnd++ = ((uint8_t*)&dstData)[1];
- }
- if (iBytes > 2) {
- *pDstEnd++ = ((uint8_t*)&dstData)[2];
- }
- }
- return pDstEnd - pDst;
-}
-int32_t FX_Base64DecodeW(const FX_WCHAR* pSrc, int32_t iSrcLen, uint8_t* pDst) {
- FXSYS_assert(pSrc != NULL);
- if (iSrcLen < 1) {
- return 0;
- }
- while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
- iSrcLen--;
- }
- if (iSrcLen < 1) {
- return 0;
- }
- if (pDst == NULL) {
- int32_t iDstLen = iSrcLen / 4 * 3;
- iSrcLen %= 4;
- if (iSrcLen == 1) {
- iDstLen += 1;
- } else if (iSrcLen == 2) {
- iDstLen += 1;
- } else if (iSrcLen == 3) {
- iDstLen += 2;
- }
- return iDstLen;
- }
- FX_CHAR srcData[4];
- FX_BASE64DATA dstData;
- int32_t iChars = 4, iBytes;
- uint8_t* pDstEnd = pDst;
- while (iSrcLen > 0) {
- if (iSrcLen > 3) {
- srcData[0] = (FX_CHAR)*pSrc++;
- srcData[1] = (FX_CHAR)*pSrc++;
- srcData[2] = (FX_CHAR)*pSrc++;
- srcData[3] = (FX_CHAR)*pSrc++;
- iSrcLen -= 4;
- } else {
- *((FX_DWORD*)&dstData) = 0;
- *((FX_DWORD*)srcData) = 0;
- srcData[0] = (FX_CHAR)*pSrc++;
- if (iSrcLen > 1) {
- srcData[1] = (FX_CHAR)*pSrc++;
- }
- if (iSrcLen > 2) {
- srcData[2] = (FX_CHAR)*pSrc++;
- }
- iChars = iSrcLen;
- iSrcLen = 0;
- }
- FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
- *pDstEnd++ = ((uint8_t*)&dstData)[0];
- if (iBytes > 1) {
- *pDstEnd++ = ((uint8_t*)&dstData)[1];
- }
- if (iBytes > 2) {
- *pDstEnd++ = ((uint8_t*)&dstData)[2];
- }
- }
- return pDstEnd - pDst;
-}
-const static uint8_t g_FXHex2DecMap[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0,
- 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12,
- 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-uint8_t FX_Hex2Dec(uint8_t hexHigh, uint8_t hexLow) {
- return (g_FXHex2DecMap[hexHigh] << 4) + g_FXHex2DecMap[hexLow];
-}
-int32_t FX_SeparateStringW(const FX_WCHAR* pStr,
- int32_t iStrLen,
- FX_WCHAR delimiter,
- CFX_WideStringArray& pieces) {
- if (pStr == NULL) {
- return 0;
- }
- if (iStrLen < 0) {
- iStrLen = FXSYS_wcslen(pStr);
- }
- const FX_WCHAR* pToken = pStr;
- const FX_WCHAR* pEnd = pStr + iStrLen;
- while (TRUE) {
- if (pStr >= pEnd || delimiter == *pStr) {
- CFX_WideString sub(pToken, pStr - pToken);
- pieces.Add(sub);
- pToken = pStr + 1;
- if (pStr >= pEnd) {
- break;
- }
- }
- pStr++;
- }
- return pieces.GetSize();
-}
-#ifdef __cplusplus
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+const static FX_CHAR g_FXBase64EncoderMap[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+};
+typedef struct _FX_BASE64DATA {
+ FX_DWORD data1 : 2;
+ FX_DWORD data2 : 6;
+ FX_DWORD data3 : 4;
+ FX_DWORD data4 : 4;
+ FX_DWORD data5 : 6;
+ FX_DWORD data6 : 2;
+ FX_DWORD data7 : 8;
+} FX_BASE64DATA, *FX_LPBASE64ENCODEDATA;
+typedef FX_BASE64DATA const* FX_LPCBASE64DATA;
+static void FX_Base64EncodePiece(const FX_BASE64DATA& src,
+ int32_t iBytes,
+ FX_CHAR dst[4]) {
+ dst[0] = g_FXBase64EncoderMap[src.data2];
+ FX_DWORD b = src.data1 << 4;
+ if (iBytes > 1) {
+ b |= src.data4;
+ }
+ dst[1] = g_FXBase64EncoderMap[b];
+ if (iBytes > 1) {
+ b = src.data3 << 2;
+ if (iBytes > 2) {
+ b |= src.data6;
+ }
+ dst[2] = g_FXBase64EncoderMap[b];
+ if (iBytes > 2) {
+ dst[3] = g_FXBase64EncoderMap[src.data5];
+ } else {
+ dst[3] = '=';
+ }
+ } else {
+ dst[2] = dst[3] = '=';
+ }
+}
+int32_t FX_Base64EncodeA(const uint8_t* pSrc, int32_t iSrcLen, FX_CHAR* pDst) {
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ int32_t iDstLen = iSrcLen / 3 * 4;
+ if ((iSrcLen % 3) != 0) {
+ iDstLen += 4;
+ }
+ return iDstLen;
+ }
+ FX_BASE64DATA srcData;
+ int32_t iBytes = 3;
+ FX_CHAR* pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 2) {
+ ((uint8_t*)&srcData)[0] = *pSrc++;
+ ((uint8_t*)&srcData)[1] = *pSrc++;
+ ((uint8_t*)&srcData)[2] = *pSrc++;
+ iSrcLen -= 3;
+ } else {
+ *((FX_DWORD*)&srcData) = 0;
+ ((uint8_t*)&srcData)[0] = *pSrc++;
+ if (iSrcLen > 1) {
+ ((uint8_t*)&srcData)[1] = *pSrc++;
+ }
+ iBytes = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64EncodePiece(srcData, iBytes, pDstEnd);
+ pDstEnd += 4;
+ }
+ return pDstEnd - pDst;
+}
+const static uint8_t g_FXBase64DecoderMap[256] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static void FX_Base64DecodePiece(const FX_CHAR src[4],
+ int32_t iChars,
+ FX_BASE64DATA& dst,
+ int32_t& iBytes) {
+ FXSYS_assert(iChars > 0 && iChars < 5);
+ iBytes = 1;
+ dst.data2 = g_FXBase64DecoderMap[(uint8_t)src[0]];
+ if (iChars > 1) {
+ uint8_t b = g_FXBase64DecoderMap[(uint8_t)src[1]];
+ dst.data1 = b >> 4;
+ dst.data4 = b;
+ if (iChars > 2) {
+ iBytes = 2;
+ b = g_FXBase64DecoderMap[(uint8_t)src[2]];
+ dst.data3 = b >> 2;
+ dst.data6 = b;
+ if (iChars > 3) {
+ iBytes = 3;
+ dst.data5 = g_FXBase64DecoderMap[(uint8_t)src[3]];
+ } else {
+ dst.data5 = 0;
+ }
+ } else {
+ dst.data3 = 0;
+ }
+ } else {
+ dst.data1 = 0;
+ }
+}
+int32_t FX_Base64DecodeA(const FX_CHAR* pSrc, int32_t iSrcLen, uint8_t* pDst) {
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
+ iSrcLen--;
+ }
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ int32_t iDstLen = iSrcLen / 4 * 3;
+ iSrcLen %= 4;
+ if (iSrcLen == 1) {
+ iDstLen += 1;
+ } else if (iSrcLen == 2) {
+ iDstLen += 1;
+ } else if (iSrcLen == 3) {
+ iDstLen += 2;
+ }
+ return iDstLen;
+ }
+ FX_CHAR srcData[4];
+ FX_BASE64DATA dstData;
+ int32_t iChars = 4, iBytes;
+ uint8_t* pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 3) {
+ *((FX_DWORD*)srcData) = *((FX_DWORD*)pSrc);
+ pSrc += 4;
+ iSrcLen -= 4;
+ } else {
+ *((FX_DWORD*)&dstData) = 0;
+ *((FX_DWORD*)srcData) = 0;
+ srcData[0] = *pSrc++;
+ if (iSrcLen > 1) {
+ srcData[1] = *pSrc++;
+ }
+ if (iSrcLen > 2) {
+ srcData[2] = *pSrc++;
+ }
+ iChars = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
+ *pDstEnd++ = ((uint8_t*)&dstData)[0];
+ if (iBytes > 1) {
+ *pDstEnd++ = ((uint8_t*)&dstData)[1];
+ }
+ if (iBytes > 2) {
+ *pDstEnd++ = ((uint8_t*)&dstData)[2];
+ }
+ }
+ return pDstEnd - pDst;
+}
+int32_t FX_Base64DecodeW(const FX_WCHAR* pSrc, int32_t iSrcLen, uint8_t* pDst) {
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
+ iSrcLen--;
+ }
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ int32_t iDstLen = iSrcLen / 4 * 3;
+ iSrcLen %= 4;
+ if (iSrcLen == 1) {
+ iDstLen += 1;
+ } else if (iSrcLen == 2) {
+ iDstLen += 1;
+ } else if (iSrcLen == 3) {
+ iDstLen += 2;
+ }
+ return iDstLen;
+ }
+ FX_CHAR srcData[4];
+ FX_BASE64DATA dstData;
+ int32_t iChars = 4, iBytes;
+ uint8_t* pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 3) {
+ srcData[0] = (FX_CHAR)*pSrc++;
+ srcData[1] = (FX_CHAR)*pSrc++;
+ srcData[2] = (FX_CHAR)*pSrc++;
+ srcData[3] = (FX_CHAR)*pSrc++;
+ iSrcLen -= 4;
+ } else {
+ *((FX_DWORD*)&dstData) = 0;
+ *((FX_DWORD*)srcData) = 0;
+ srcData[0] = (FX_CHAR)*pSrc++;
+ if (iSrcLen > 1) {
+ srcData[1] = (FX_CHAR)*pSrc++;
+ }
+ if (iSrcLen > 2) {
+ srcData[2] = (FX_CHAR)*pSrc++;
+ }
+ iChars = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
+ *pDstEnd++ = ((uint8_t*)&dstData)[0];
+ if (iBytes > 1) {
+ *pDstEnd++ = ((uint8_t*)&dstData)[1];
+ }
+ if (iBytes > 2) {
+ *pDstEnd++ = ((uint8_t*)&dstData)[2];
+ }
+ }
+ return pDstEnd - pDst;
+}
+const static uint8_t g_FXHex2DecMap[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0,
+ 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12,
+ 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+uint8_t FX_Hex2Dec(uint8_t hexHigh, uint8_t hexLow) {
+ return (g_FXHex2DecMap[hexHigh] << 4) + g_FXHex2DecMap[hexLow];
+}
+int32_t FX_SeparateStringW(const FX_WCHAR* pStr,
+ int32_t iStrLen,
+ FX_WCHAR delimiter,
+ CFX_WideStringArray& pieces) {
+ if (pStr == NULL) {
+ return 0;
+ }
+ if (iStrLen < 0) {
+ iStrLen = FXSYS_wcslen(pStr);
+ }
+ const FX_WCHAR* pToken = pStr;
+ const FX_WCHAR* pEnd = pStr + iStrLen;
+ while (TRUE) {
+ if (pStr >= pEnd || delimiter == *pStr) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ pieces.Add(sub);
+ pToken = pStr + 1;
+ if (pStr >= pEnd) {
+ break;
+ }
+ }
+ pStr++;
+ }
+ return pieces.GetSize();
+}
+#ifdef __cplusplus
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_codepage.cpp b/xfa/src/fgas/src/crt/fx_codepage.cpp
index 9348d33065..16c363bd14 100644
--- a/xfa/src/fgas/src/crt/fx_codepage.cpp
+++ b/xfa/src/fgas/src/crt/fx_codepage.cpp
@@ -1,340 +1,340 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-static const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = {
- {0, 1252}, {1, 0}, {2, 42}, {77, 10000}, {78, 10001},
- {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, {84, 10004},
- {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, {89, 10007},
- {128, 932}, {129, 949}, {130, 1361}, {134, 936}, {136, 950},
- {161, 1253}, {162, 1254}, {163, 1258}, {177, 1255}, {178, 1256},
- {186, 1257}, {204, 1251}, {222, 874}, {238, 1250}, {254, 437},
- {255, 850},
-};
-FX_WORD FX_GetCodePageFromCharset(uint8_t charset) {
- int32_t iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1;
- FXSYS_assert(iEnd >= 0);
- int32_t iStart = 0, iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const FX_CHARSET_MAP& cp = g_FXCharset2CodePageTable[iMid];
- if (charset == cp.charset) {
- return cp.codepage;
- } else if (charset < cp.charset) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- return 0xFFFF;
-}
-static const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = {
- {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874},
- {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250},
- {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255},
- {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000},
- {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005},
- {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029},
- {89, 10007},
-};
-FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage) {
- int32_t iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1;
- FXSYS_assert(iEnd >= 0);
- int32_t iStart = 0, iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const FX_CHARSET_MAP& cp = g_FXCodepage2CharsetTable[iMid];
- if (codepage == cp.codepage) {
- return cp.charset;
- } else if (codepage < cp.codepage) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- return 0xFFFF;
-}
-const FX_LANG2CPMAP g_FXLang2CodepageTable[] = {
- {FX_LANG_Arabic_SaudiArabia, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Bulgarian_Bulgaria, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Catalan_Catalan, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Chinese_Taiwan, FX_CODEPAGE_ChineseTraditional},
- {FX_LANG_CzechRepublic, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Danish_Denmark, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_German_Germany, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Greek_Greece, FX_CODEPAGE_MSWin_Greek},
- {FX_LANG_English_UnitedStates, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_TraditionalSort, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Finnish_Finland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_France, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Hebrew_Israel, FX_CODEPAGE_MSWin_Hebrew},
- {FX_LANG_Hungarian_Hungary, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Icelandic_Iceland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Italian_Italy, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Japanese_Japan, FX_CODEPAGE_ShiftJIS},
- {FX_LANG_Korean_Korea, FX_CODEPAGE_Korean},
- {FX_LANG_Dutch_Netherlands, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Norwegian_Bokmal, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Polish_Poland, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Portuguese_Brazil, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Romanian_Romania, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Russian_Russia, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Croatian_Croatia, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Slovak_Slovakia, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Albanian_Albania, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Swedish_Sweden, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Thai_Thailand, FX_CODEPAGE_MSDOS_Thai},
- {FX_LANG_Turkish_Turkey, FX_CODEPAGE_MSWin_Turkish},
- {FX_LANG_Urdu_Pakistan, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Indonesian_Indonesia, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Ukrainian_Ukraine, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Belarusian_Belarus, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Slovenian_Slovenia, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Estonian_Estonia, FX_CODEPAGE_MSWin_Baltic},
- {FX_LANG_Latvian_Latvia, FX_CODEPAGE_MSWin_Baltic},
- {FX_LANG_Lithuanian_Lithuania, FX_CODEPAGE_MSWin_Baltic},
- {FX_LANG_Persian, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Vietnamese_Vietnam, FX_CODEPAGE_MSWin_Vietnamese},
- {FX_LANG_Armenian_Armenia, FX_CODEPAGE_DefANSI},
- {FX_LANG_Azerbaijan_Latin, FX_CODEPAGE_MSWin_Turkish},
- {FX_LANG_Basque_Basque, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Macedonian, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Afrikaans_SouthAfrica, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Georgian_Georgia, FX_CODEPAGE_DefANSI},
- {FX_LANG_Faroese_FaroeIslands, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Hindi_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Malay_Malaysia, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Kazakh_Kazakhstan, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Kyrgyz_Kyrgyzstan, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Kiswahili_Kenya, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Uzbek_LatinUzbekistan, FX_CODEPAGE_MSWin_Turkish},
- {FX_LANG_Tatar_Russia, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Punjabi_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Gujarati_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Tamil_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Telugu_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Kannada_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Marathi_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_SanskritIndia, FX_CODEPAGE_DefANSI},
- {FX_LANG_Mongolian_CyrillicMongolia, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Galician_Galician, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Konkani_India, FX_CODEPAGE_DefANSI},
- {FX_LANG_Syriac_Syria, FX_CODEPAGE_DefANSI},
- {FX_LANG_Divehi_Maldives, FX_CODEPAGE_DefANSI},
- {FX_LANG_Arabic_Iraq, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Chinese_PRC, FX_CODEPAGE_ChineseSimplified},
- {FX_LANG_German_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_English_UnitedKingdom, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Mexico, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_Belgium, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Italian_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Dutch_Belgium, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Norwegian_Nynorsk, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Portuguese_Portugal, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_SerbianLatin_Serbia, FX_CODEPAGE_MSWin_EasternEuropean},
- {FX_LANG_Swedish_Finland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Azerbaijan_Cyrillic, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Malay_BruneiDarussalam, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Uzbek_CyrillicUzbekistan, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Arabic_Egypt, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Chinese_HongKong, FX_CODEPAGE_ChineseTraditional},
- {FX_LANG_German_Austria, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_English_Australia, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_InternationalSort, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_Canada, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_SerbianCyrillic_Serbia, FX_CODEPAGE_MSWin_Cyrillic},
- {FX_LANG_Arabic_Libya, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Chinese_Singapore, FX_CODEPAGE_ChineseSimplified},
- {FX_LANG_German_Luxembourg, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_English_Canada, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Guatemala, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Algeria, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Chinese_Macao, FX_CODEPAGE_ChineseTraditional},
- {FX_LANG_German_Liechtenstein, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_English_NewZealand, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_CostaRica, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_Luxembourg, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Morocco, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Ireland, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Panama, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_French_Monaco, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Tunisia, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_SouthAfrica, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_DominicanRepublic, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Oman, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Jamaica, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Venezuela, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Yemen, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Caribbean, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Colombia, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Syria, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Belize, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Peru, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Jordan, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_TrinidadTobago, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Argentina, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Lebanon, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Zimbabwe, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Ecuador, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Kuwait, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_English_Philippines, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Chile, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_UAE, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Spanish_Uruguay, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Bahrain, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Spanish_Paraguay, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Arabic_Qatar, FX_CODEPAGE_MSWin_Arabic},
- {FX_LANG_Spanish_Bolivia, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_ElSalvador, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Honduras, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_Nicaragua, FX_CODEPAGE_MSWin_WesternEuropean},
- {FX_LANG_Spanish_PuertoRico, FX_CODEPAGE_MSWin_WesternEuropean},
-};
-FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage) {
- int32_t iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1;
- FXSYS_assert(iEnd >= 0);
- int32_t iStart = 0, iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const FX_LANG2CPMAP& cp = g_FXLang2CodepageTable[iMid];
- if (wLanguage == cp.wLanguage) {
- return cp.wCodepage;
- } else if (wLanguage < cp.wLanguage) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- return 0xFFFF;
-}
-static const FX_STR2CPHASH g_FXCPHashTable[] = {
- {0xd45, 0x6faf}, {0xd46, 0x6fb0}, {0xd47, 0x6fb1},
- {0xd48, 0x6fb2}, {0xd49, 0x4e6}, {0xd4d, 0x6fbd},
- {0xe9e, 0x4e4}, {0xc998, 0x1b5}, {0x18ef0, 0x3a8},
- {0x19f85, 0x5182}, {0x2e2335, 0x3b6}, {0x325153, 0x5182},
- {0x145bded, 0x2716}, {0x3c9a5f2, 0xc6f3}, {0x4c45f2d, 0x3a4},
- {0x4c45f4e, 0xc431}, {0x58caf51, 0x4e4}, {0x5a5cd7d, 0x3a8},
- {0x5a6c6a7, 0x4e4}, {0x5a6ca0b, 0x1b5}, {0x5a6cd68, 0x307},
- {0x5a6d8d3, 0x4e4}, {0x5a6d948, 0x354}, {0x5a6d96b, 0x362},
- {0x5a6d984, 0x366}, {0x5a90e35, 0x1b5}, {0x5e0cf00, 0x6fb5},
- {0x609c324, 0x551}, {0x617d97f, 0x5182}, {0x6a6fd91, 0xfde8},
- {0x6a6fd92, 0xfde9}, {0x6b102de, 0xcadc}, {0x6b10f48, 0x4e89},
- {0x1020805f, 0x4e4}, {0x10f0524c, 0x6fb5}, {0x11d558fe, 0x6fb0},
- {0x13898d19, 0xc42d}, {0x13898d3a, 0xc431}, {0x138a319e, 0x6fb1},
- {0x14679c09, 0x96c6}, {0x153f0a3d, 0x6fb2}, {0x1576eeb3, 0x4e20},
- {0x169a0ce6, 0xc6f9}, {0x16f3e2dc, 0x6fb3}, {0x18a8bb7a, 0x6fb4},
- {0x1a5d9419, 0x6fb5}, {0x1a847b48, 0x3a8}, {0x1b762419, 0xcec8},
- {0x1b9d7847, 0x475}, {0x1c126cb9, 0x6fb6}, {0x1ccdbc7d, 0x4f42},
- {0x1d330f5f, 0x2714}, {0x1dc74559, 0x4e6}, {0x1edd80da, 0x4e4},
- {0x23e4b03d, 0xfde8}, {0x24f28a16, 0x4f3d}, {0x286e7a32, 0x2715},
- {0x2c7c18ed, 0x3a8}, {0x2e2103b7, 0x2713}, {0x304bf479, 0x6fb4},
- {0x304bf47d, 0x6fb5}, {0x309bb869, 0xfde8}, {0x309bb86a, 0xfde9},
- {0x33664357, 0x3b6}, {0x352d6b49, 0x3a4}, {0x36f5661c, 0x1b5},
- {0x392e8f48, 0xcadc}, {0x3dc7c64c, 0x47c}, {0x3ed2e8e1, 0x4e4},
- {0x3f0c2fea, 0xcaed}, {0x3f0fef8f, 0xc6f2}, {0x3f5e130f, 0x5182},
- {0x47174d1f, 0x3a8}, {0x49686b7b, 0x6fb4}, {0x4b80b0d9, 0x3a4},
- {0x4dcda97a, 0x4e4}, {0x4dcda9b6, 0x4e4}, {0x4e881e6a, 0x5221},
- {0x4ffdf5a1, 0x36a}, {0x4ffdf5a5, 0x6fbd}, {0x5241ce16, 0x4e8b},
- {0x546bab9d, 0x4e4}, {0x54a3d64e, 0x6fb6}, {0x562179bd, 0x5161},
- {0x57c1df15, 0xc6f7}, {0x61ff6e62, 0x4f36}, {0x6359c7d8, 0x4f35},
- {0x63f3c335, 0x3a8}, {0x645a0f78, 0x477}, {0x691ac2fd, 0x275f},
- {0x6dc2eab0, 0x2d0}, {0x6dc2eeef, 0x35e}, {0x6dc2ef10, 0x36a},
- {0x7103138a, 0x47d}, {0x710dfbd0, 0xc6f5}, {0x7319f6cb, 0x36a},
- {0x745096ad, 0x3a8}, {0x74866229, 0x4e8c}, {0x77185fa5, 0x3a8},
- {0x7953f002, 0x6faf}, {0x7953f003, 0x6fb0}, {0x7953f004, 0x6fb1},
- {0x7953f005, 0x6fb2}, {0x7953f006, 0x6fb7}, {0x7953f00a, 0x6fbd},
- {0x7c577571, 0x2761}, {0x7e8c8ff1, 0x479}, {0x8031f47f, 0x3b5},
- {0x8031f481, 0x3b5}, {0x80c4a710, 0x5187}, {0x857c7e14, 0xfde8},
- {0x857c7e15, 0xfde9}, {0x86b59c90, 0x4e4}, {0x86b59c91, 0x6fb0},
- {0x86b59c92, 0x6fb1}, {0x86b59c93, 0x6fb2}, {0x86b59c94, 0x6fb3},
- {0x86b59c95, 0x6fb4}, {0x86b59c96, 0x6fb5}, {0x86b59c97, 0x4e7},
- {0x86b59c98, 0x4e6}, {0x8b4b24ec, 0x5190}, {0x8face362, 0x4e4},
- {0x8ff9ec2a, 0xfde9}, {0x919d3989, 0xcadc}, {0x9967e5ad, 0x4e22},
- {0x99f8b933, 0x6fbd}, {0x9bd2a380, 0x4fc7}, {0x9befad23, 0x4f38},
- {0x9c7ac649, 0x4f3c}, {0xa02468db, 0xdeae}, {0xa02468ec, 0xdeab},
- {0xa024692a, 0xdeaa}, {0xa0246997, 0xdeb2}, {0xa02469ff, 0xdeb0},
- {0xa0246a3d, 0xdeb1}, {0xa0246a8c, 0xdeaf}, {0xa0246a9a, 0xdeb3},
- {0xa0246b16, 0xdeac}, {0xa0246b1a, 0xdead}, {0xa071addc, 0x4b1},
- {0xa38b62dc, 0x474}, {0xa4c09fed, 0x3a8}, {0xa51e86e5, 0x4e7},
- {0xa67ab13e, 0x3a4}, {0xa7414244, 0x51a9}, {0xa9ddbead, 0xc6fb},
- {0xab24ffab, 0x4e8a}, {0xabef8ac4, 0x2710}, {0xabfa20ac, 0x6fb4},
- {0xad36895e, 0x4e2}, {0xad36895f, 0x4e3}, {0xaf310e90, 0x402},
- {0xaf31166f, 0x4e8}, {0xaf7277a5, 0x3b6}, {0xafc0d8b3, 0x96c6},
- {0xb0fd5dba, 0xcae0}, {0xb0fd5e95, 0xcadc}, {0xb1052893, 0x7149},
- {0xb1e98745, 0x36a}, {0xb277e91c, 0x5166}, {0xb2f7eac5, 0xcae0},
- {0xb2f7eba0, 0xcadc}, {0xb2f7ebc1, 0x3b5}, {0xb53fa77d, 0x3a8},
- {0xb6391138, 0x6fb5}, {0xb7358b7f, 0x6fb6}, {0xb8c42b40, 0x4e4},
- {0xb8c42ea4, 0x1b5}, {0xb8c439e7, 0x2e1}, {0xb8c43a61, 0x307},
- {0xb8c43d6c, 0x4e4}, {0xb8c43ddf, 0x352}, {0xb8c43de1, 0x354},
- {0xb8c43de6, 0x359}, {0xb8c43dff, 0x35d}, {0xb8c43e04, 0x362},
- {0xb8c43e07, 0x365}, {0xbcd29a7f, 0x3a8}, {0xbce34e78, 0x5182},
- {0xbce34e7b, 0x556a}, {0xbce81504, 0x3b5}, {0xbd8a4c95, 0x272d},
- {0xbdd89dad, 0x4e4}, {0xbdd89dae, 0x6fb0}, {0xbdd89daf, 0x6fb1},
- {0xbdd89db0, 0x6fb2}, {0xbdd89db1, 0x4e6}, {0xbdd89db5, 0x6fbd},
- {0xc1756e9f, 0x36b}, {0xc7482444, 0x47a}, {0xc9281c18, 0x4e4},
- {0xc9ef95df, 0x47b}, {0xccc9db0d, 0x4e4}, {0xccc9db0e, 0x6fb0},
- {0xcd73425f, 0x3b6}, {0xce38b40b, 0x4b0}, {0xce99e549, 0x25},
- {0xcf598740, 0x4e7}, {0xcf6d6f78, 0x4e4}, {0xcf758df6, 0x3a4},
- {0xd1266e51, 0x6fb5}, {0xd2910213, 0x2718}, {0xd29196bb, 0x2712},
- {0xd3eb2fc2, 0x476}, {0xd442dc2c, 0x4fc4}, {0xd9da4da4, 0x2711},
- {0xdbad2f42, 0x4e4}, {0xdbad2f43, 0x6fb0}, {0xdbad2f44, 0x6fb1},
- {0xdbad2f45, 0x6fb2}, {0xdbad2f46, 0x6fb3}, {0xdbad2f47, 0x6fb4},
- {0xdbad2f48, 0x6fb5}, {0xdbad2f49, 0x6fb6}, {0xdbad2f4a, 0x4e6},
- {0xdc438033, 0x4f31}, {0xdccb439b, 0x477}, {0xdccdc626, 0x3b5},
- {0xdd80a595, 0x4e4}, {0xdd80a596, 0x6fb0}, {0xdd80a59e, 0x6fb1},
- {0xdd80a5b4, 0x6fb2}, {0xdd80a5d9, 0x6fb5}, {0xdd80a5da, 0x6fb4},
- {0xdd80a5fa, 0x6fb6}, {0xdd80a615, 0x6fb3}, {0xdd80a619, 0x4e6},
- {0xdd80a61a, 0x3b5}, {0xdd80c0f8, 0x4e9f}, {0xdf7e46ff, 0x4fc8},
- {0xdf8680fd, 0x556a}, {0xdfb0bd6e, 0xc42d}, {0xdff05486, 0x2c4},
- {0xe3323399, 0x3a4}, {0xe60412dd, 0x3b5}, {0xeee47add, 0x4b0},
- {0xf021a186, 0x4e2}, {0xf021a187, 0x4e3}, {0xf021a188, 0x4e4},
- {0xf021a189, 0x4e5}, {0xf021a18a, 0x4e6}, {0xf021a18b, 0x4e7},
- {0xf021a18c, 0x4e8}, {0xf021a18d, 0x4e9}, {0xf021a18e, 0x4ea},
- {0xf0700456, 0x6fb3}, {0xf274f175, 0x3b5}, {0xf2a9730b, 0x3a8},
- {0xf3d463c2, 0x3a4}, {0xf52a70a3, 0xc42e}, {0xf5693147, 0x6fb3},
- {0xf637e157, 0x478}, {0xfc213f3a, 0x2717}, {0xff654d14, 0x3b5},
-};
-FX_WORD FX_GetCodePageFromStringA(const FX_CHAR* pStr, int32_t iLength) {
- FXSYS_assert(pStr != NULL);
- if (iLength < 0) {
- iLength = FXSYS_strlen(pStr);
- }
- if (iLength == 0) {
- return 0xFFFF;
- }
- uint32_t uHash = FX_HashCode_String_GetA(pStr, iLength, TRUE);
- int32_t iStart = 0, iMid;
- int32_t iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1;
- FXSYS_assert(iEnd >= 0);
- do {
- iMid = (iStart + iEnd) / 2;
- const FX_STR2CPHASH& cp = g_FXCPHashTable[iMid];
- if (uHash == cp.uHash) {
- return (FX_WORD)cp.uCodePage;
- } else if (uHash < cp.uHash) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- return 0xFFFF;
-}
-FX_WORD FX_GetCodePageFormStringW(const FX_WCHAR* pStr, int32_t iLength) {
- if (iLength < 0) {
- iLength = FXSYS_wcslen(pStr);
- }
- if (iLength == 0) {
- return 0xFFFF;
- }
- CFX_ByteString csStr;
- FX_CHAR* pBuf = csStr.GetBuffer(iLength + 1);
- for (int32_t i = 0; i < iLength; ++i) {
- *pBuf++ = (FX_CHAR)*pStr++;
- }
- csStr.ReleaseBuffer(iLength);
- return FX_GetCodePageFromStringA(csStr, iLength);
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+static const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = {
+ {0, 1252}, {1, 0}, {2, 42}, {77, 10000}, {78, 10001},
+ {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, {84, 10004},
+ {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, {89, 10007},
+ {128, 932}, {129, 949}, {130, 1361}, {134, 936}, {136, 950},
+ {161, 1253}, {162, 1254}, {163, 1258}, {177, 1255}, {178, 1256},
+ {186, 1257}, {204, 1251}, {222, 874}, {238, 1250}, {254, 437},
+ {255, 850},
+};
+FX_WORD FX_GetCodePageFromCharset(uint8_t charset) {
+ int32_t iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ int32_t iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_CHARSET_MAP& cp = g_FXCharset2CodePageTable[iMid];
+ if (charset == cp.charset) {
+ return cp.codepage;
+ } else if (charset < cp.charset) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+static const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = {
+ {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874},
+ {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250},
+ {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255},
+ {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000},
+ {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005},
+ {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029},
+ {89, 10007},
+};
+FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage) {
+ int32_t iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ int32_t iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_CHARSET_MAP& cp = g_FXCodepage2CharsetTable[iMid];
+ if (codepage == cp.codepage) {
+ return cp.charset;
+ } else if (codepage < cp.codepage) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+const FX_LANG2CPMAP g_FXLang2CodepageTable[] = {
+ {FX_LANG_Arabic_SaudiArabia, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Bulgarian_Bulgaria, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Catalan_Catalan, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Chinese_Taiwan, FX_CODEPAGE_ChineseTraditional},
+ {FX_LANG_CzechRepublic, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Danish_Denmark, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_German_Germany, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Greek_Greece, FX_CODEPAGE_MSWin_Greek},
+ {FX_LANG_English_UnitedStates, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_TraditionalSort, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Finnish_Finland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_France, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Hebrew_Israel, FX_CODEPAGE_MSWin_Hebrew},
+ {FX_LANG_Hungarian_Hungary, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Icelandic_Iceland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Italian_Italy, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Japanese_Japan, FX_CODEPAGE_ShiftJIS},
+ {FX_LANG_Korean_Korea, FX_CODEPAGE_Korean},
+ {FX_LANG_Dutch_Netherlands, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Norwegian_Bokmal, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Polish_Poland, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Portuguese_Brazil, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Romanian_Romania, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Russian_Russia, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Croatian_Croatia, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Slovak_Slovakia, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Albanian_Albania, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Swedish_Sweden, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Thai_Thailand, FX_CODEPAGE_MSDOS_Thai},
+ {FX_LANG_Turkish_Turkey, FX_CODEPAGE_MSWin_Turkish},
+ {FX_LANG_Urdu_Pakistan, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Indonesian_Indonesia, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Ukrainian_Ukraine, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Belarusian_Belarus, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Slovenian_Slovenia, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Estonian_Estonia, FX_CODEPAGE_MSWin_Baltic},
+ {FX_LANG_Latvian_Latvia, FX_CODEPAGE_MSWin_Baltic},
+ {FX_LANG_Lithuanian_Lithuania, FX_CODEPAGE_MSWin_Baltic},
+ {FX_LANG_Persian, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Vietnamese_Vietnam, FX_CODEPAGE_MSWin_Vietnamese},
+ {FX_LANG_Armenian_Armenia, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Azerbaijan_Latin, FX_CODEPAGE_MSWin_Turkish},
+ {FX_LANG_Basque_Basque, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Macedonian, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Afrikaans_SouthAfrica, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Georgian_Georgia, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Faroese_FaroeIslands, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Hindi_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Malay_Malaysia, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Kazakh_Kazakhstan, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Kyrgyz_Kyrgyzstan, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Kiswahili_Kenya, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Uzbek_LatinUzbekistan, FX_CODEPAGE_MSWin_Turkish},
+ {FX_LANG_Tatar_Russia, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Punjabi_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Gujarati_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Tamil_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Telugu_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Kannada_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Marathi_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_SanskritIndia, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Mongolian_CyrillicMongolia, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Galician_Galician, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Konkani_India, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Syriac_Syria, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Divehi_Maldives, FX_CODEPAGE_DefANSI},
+ {FX_LANG_Arabic_Iraq, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Chinese_PRC, FX_CODEPAGE_ChineseSimplified},
+ {FX_LANG_German_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_UnitedKingdom, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Mexico, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Belgium, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Italian_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Dutch_Belgium, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Norwegian_Nynorsk, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Portuguese_Portugal, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_SerbianLatin_Serbia, FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Swedish_Finland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Azerbaijan_Cyrillic, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Malay_BruneiDarussalam, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Uzbek_CyrillicUzbekistan, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Arabic_Egypt, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Chinese_HongKong, FX_CODEPAGE_ChineseTraditional},
+ {FX_LANG_German_Austria, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_Australia, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_InternationalSort, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Canada, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_SerbianCyrillic_Serbia, FX_CODEPAGE_MSWin_Cyrillic},
+ {FX_LANG_Arabic_Libya, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Chinese_Singapore, FX_CODEPAGE_ChineseSimplified},
+ {FX_LANG_German_Luxembourg, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_Canada, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Guatemala, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Switzerland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Algeria, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Chinese_Macao, FX_CODEPAGE_ChineseTraditional},
+ {FX_LANG_German_Liechtenstein, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_NewZealand, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_CostaRica, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Luxembourg, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Morocco, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Ireland, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Panama, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Monaco, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Tunisia, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_SouthAfrica, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_DominicanRepublic, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Oman, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Jamaica, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Venezuela, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Yemen, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Caribbean, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Colombia, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Syria, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Belize, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Peru, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Jordan, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_TrinidadTobago, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Argentina, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Lebanon, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Zimbabwe, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Ecuador, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Kuwait, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_English_Philippines, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Chile, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_UAE, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Spanish_Uruguay, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Bahrain, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Spanish_Paraguay, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Qatar, FX_CODEPAGE_MSWin_Arabic},
+ {FX_LANG_Spanish_Bolivia, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_ElSalvador, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Honduras, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Nicaragua, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_PuertoRico, FX_CODEPAGE_MSWin_WesternEuropean},
+};
+FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage) {
+ int32_t iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ int32_t iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_LANG2CPMAP& cp = g_FXLang2CodepageTable[iMid];
+ if (wLanguage == cp.wLanguage) {
+ return cp.wCodepage;
+ } else if (wLanguage < cp.wLanguage) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+static const FX_STR2CPHASH g_FXCPHashTable[] = {
+ {0xd45, 0x6faf}, {0xd46, 0x6fb0}, {0xd47, 0x6fb1},
+ {0xd48, 0x6fb2}, {0xd49, 0x4e6}, {0xd4d, 0x6fbd},
+ {0xe9e, 0x4e4}, {0xc998, 0x1b5}, {0x18ef0, 0x3a8},
+ {0x19f85, 0x5182}, {0x2e2335, 0x3b6}, {0x325153, 0x5182},
+ {0x145bded, 0x2716}, {0x3c9a5f2, 0xc6f3}, {0x4c45f2d, 0x3a4},
+ {0x4c45f4e, 0xc431}, {0x58caf51, 0x4e4}, {0x5a5cd7d, 0x3a8},
+ {0x5a6c6a7, 0x4e4}, {0x5a6ca0b, 0x1b5}, {0x5a6cd68, 0x307},
+ {0x5a6d8d3, 0x4e4}, {0x5a6d948, 0x354}, {0x5a6d96b, 0x362},
+ {0x5a6d984, 0x366}, {0x5a90e35, 0x1b5}, {0x5e0cf00, 0x6fb5},
+ {0x609c324, 0x551}, {0x617d97f, 0x5182}, {0x6a6fd91, 0xfde8},
+ {0x6a6fd92, 0xfde9}, {0x6b102de, 0xcadc}, {0x6b10f48, 0x4e89},
+ {0x1020805f, 0x4e4}, {0x10f0524c, 0x6fb5}, {0x11d558fe, 0x6fb0},
+ {0x13898d19, 0xc42d}, {0x13898d3a, 0xc431}, {0x138a319e, 0x6fb1},
+ {0x14679c09, 0x96c6}, {0x153f0a3d, 0x6fb2}, {0x1576eeb3, 0x4e20},
+ {0x169a0ce6, 0xc6f9}, {0x16f3e2dc, 0x6fb3}, {0x18a8bb7a, 0x6fb4},
+ {0x1a5d9419, 0x6fb5}, {0x1a847b48, 0x3a8}, {0x1b762419, 0xcec8},
+ {0x1b9d7847, 0x475}, {0x1c126cb9, 0x6fb6}, {0x1ccdbc7d, 0x4f42},
+ {0x1d330f5f, 0x2714}, {0x1dc74559, 0x4e6}, {0x1edd80da, 0x4e4},
+ {0x23e4b03d, 0xfde8}, {0x24f28a16, 0x4f3d}, {0x286e7a32, 0x2715},
+ {0x2c7c18ed, 0x3a8}, {0x2e2103b7, 0x2713}, {0x304bf479, 0x6fb4},
+ {0x304bf47d, 0x6fb5}, {0x309bb869, 0xfde8}, {0x309bb86a, 0xfde9},
+ {0x33664357, 0x3b6}, {0x352d6b49, 0x3a4}, {0x36f5661c, 0x1b5},
+ {0x392e8f48, 0xcadc}, {0x3dc7c64c, 0x47c}, {0x3ed2e8e1, 0x4e4},
+ {0x3f0c2fea, 0xcaed}, {0x3f0fef8f, 0xc6f2}, {0x3f5e130f, 0x5182},
+ {0x47174d1f, 0x3a8}, {0x49686b7b, 0x6fb4}, {0x4b80b0d9, 0x3a4},
+ {0x4dcda97a, 0x4e4}, {0x4dcda9b6, 0x4e4}, {0x4e881e6a, 0x5221},
+ {0x4ffdf5a1, 0x36a}, {0x4ffdf5a5, 0x6fbd}, {0x5241ce16, 0x4e8b},
+ {0x546bab9d, 0x4e4}, {0x54a3d64e, 0x6fb6}, {0x562179bd, 0x5161},
+ {0x57c1df15, 0xc6f7}, {0x61ff6e62, 0x4f36}, {0x6359c7d8, 0x4f35},
+ {0x63f3c335, 0x3a8}, {0x645a0f78, 0x477}, {0x691ac2fd, 0x275f},
+ {0x6dc2eab0, 0x2d0}, {0x6dc2eeef, 0x35e}, {0x6dc2ef10, 0x36a},
+ {0x7103138a, 0x47d}, {0x710dfbd0, 0xc6f5}, {0x7319f6cb, 0x36a},
+ {0x745096ad, 0x3a8}, {0x74866229, 0x4e8c}, {0x77185fa5, 0x3a8},
+ {0x7953f002, 0x6faf}, {0x7953f003, 0x6fb0}, {0x7953f004, 0x6fb1},
+ {0x7953f005, 0x6fb2}, {0x7953f006, 0x6fb7}, {0x7953f00a, 0x6fbd},
+ {0x7c577571, 0x2761}, {0x7e8c8ff1, 0x479}, {0x8031f47f, 0x3b5},
+ {0x8031f481, 0x3b5}, {0x80c4a710, 0x5187}, {0x857c7e14, 0xfde8},
+ {0x857c7e15, 0xfde9}, {0x86b59c90, 0x4e4}, {0x86b59c91, 0x6fb0},
+ {0x86b59c92, 0x6fb1}, {0x86b59c93, 0x6fb2}, {0x86b59c94, 0x6fb3},
+ {0x86b59c95, 0x6fb4}, {0x86b59c96, 0x6fb5}, {0x86b59c97, 0x4e7},
+ {0x86b59c98, 0x4e6}, {0x8b4b24ec, 0x5190}, {0x8face362, 0x4e4},
+ {0x8ff9ec2a, 0xfde9}, {0x919d3989, 0xcadc}, {0x9967e5ad, 0x4e22},
+ {0x99f8b933, 0x6fbd}, {0x9bd2a380, 0x4fc7}, {0x9befad23, 0x4f38},
+ {0x9c7ac649, 0x4f3c}, {0xa02468db, 0xdeae}, {0xa02468ec, 0xdeab},
+ {0xa024692a, 0xdeaa}, {0xa0246997, 0xdeb2}, {0xa02469ff, 0xdeb0},
+ {0xa0246a3d, 0xdeb1}, {0xa0246a8c, 0xdeaf}, {0xa0246a9a, 0xdeb3},
+ {0xa0246b16, 0xdeac}, {0xa0246b1a, 0xdead}, {0xa071addc, 0x4b1},
+ {0xa38b62dc, 0x474}, {0xa4c09fed, 0x3a8}, {0xa51e86e5, 0x4e7},
+ {0xa67ab13e, 0x3a4}, {0xa7414244, 0x51a9}, {0xa9ddbead, 0xc6fb},
+ {0xab24ffab, 0x4e8a}, {0xabef8ac4, 0x2710}, {0xabfa20ac, 0x6fb4},
+ {0xad36895e, 0x4e2}, {0xad36895f, 0x4e3}, {0xaf310e90, 0x402},
+ {0xaf31166f, 0x4e8}, {0xaf7277a5, 0x3b6}, {0xafc0d8b3, 0x96c6},
+ {0xb0fd5dba, 0xcae0}, {0xb0fd5e95, 0xcadc}, {0xb1052893, 0x7149},
+ {0xb1e98745, 0x36a}, {0xb277e91c, 0x5166}, {0xb2f7eac5, 0xcae0},
+ {0xb2f7eba0, 0xcadc}, {0xb2f7ebc1, 0x3b5}, {0xb53fa77d, 0x3a8},
+ {0xb6391138, 0x6fb5}, {0xb7358b7f, 0x6fb6}, {0xb8c42b40, 0x4e4},
+ {0xb8c42ea4, 0x1b5}, {0xb8c439e7, 0x2e1}, {0xb8c43a61, 0x307},
+ {0xb8c43d6c, 0x4e4}, {0xb8c43ddf, 0x352}, {0xb8c43de1, 0x354},
+ {0xb8c43de6, 0x359}, {0xb8c43dff, 0x35d}, {0xb8c43e04, 0x362},
+ {0xb8c43e07, 0x365}, {0xbcd29a7f, 0x3a8}, {0xbce34e78, 0x5182},
+ {0xbce34e7b, 0x556a}, {0xbce81504, 0x3b5}, {0xbd8a4c95, 0x272d},
+ {0xbdd89dad, 0x4e4}, {0xbdd89dae, 0x6fb0}, {0xbdd89daf, 0x6fb1},
+ {0xbdd89db0, 0x6fb2}, {0xbdd89db1, 0x4e6}, {0xbdd89db5, 0x6fbd},
+ {0xc1756e9f, 0x36b}, {0xc7482444, 0x47a}, {0xc9281c18, 0x4e4},
+ {0xc9ef95df, 0x47b}, {0xccc9db0d, 0x4e4}, {0xccc9db0e, 0x6fb0},
+ {0xcd73425f, 0x3b6}, {0xce38b40b, 0x4b0}, {0xce99e549, 0x25},
+ {0xcf598740, 0x4e7}, {0xcf6d6f78, 0x4e4}, {0xcf758df6, 0x3a4},
+ {0xd1266e51, 0x6fb5}, {0xd2910213, 0x2718}, {0xd29196bb, 0x2712},
+ {0xd3eb2fc2, 0x476}, {0xd442dc2c, 0x4fc4}, {0xd9da4da4, 0x2711},
+ {0xdbad2f42, 0x4e4}, {0xdbad2f43, 0x6fb0}, {0xdbad2f44, 0x6fb1},
+ {0xdbad2f45, 0x6fb2}, {0xdbad2f46, 0x6fb3}, {0xdbad2f47, 0x6fb4},
+ {0xdbad2f48, 0x6fb5}, {0xdbad2f49, 0x6fb6}, {0xdbad2f4a, 0x4e6},
+ {0xdc438033, 0x4f31}, {0xdccb439b, 0x477}, {0xdccdc626, 0x3b5},
+ {0xdd80a595, 0x4e4}, {0xdd80a596, 0x6fb0}, {0xdd80a59e, 0x6fb1},
+ {0xdd80a5b4, 0x6fb2}, {0xdd80a5d9, 0x6fb5}, {0xdd80a5da, 0x6fb4},
+ {0xdd80a5fa, 0x6fb6}, {0xdd80a615, 0x6fb3}, {0xdd80a619, 0x4e6},
+ {0xdd80a61a, 0x3b5}, {0xdd80c0f8, 0x4e9f}, {0xdf7e46ff, 0x4fc8},
+ {0xdf8680fd, 0x556a}, {0xdfb0bd6e, 0xc42d}, {0xdff05486, 0x2c4},
+ {0xe3323399, 0x3a4}, {0xe60412dd, 0x3b5}, {0xeee47add, 0x4b0},
+ {0xf021a186, 0x4e2}, {0xf021a187, 0x4e3}, {0xf021a188, 0x4e4},
+ {0xf021a189, 0x4e5}, {0xf021a18a, 0x4e6}, {0xf021a18b, 0x4e7},
+ {0xf021a18c, 0x4e8}, {0xf021a18d, 0x4e9}, {0xf021a18e, 0x4ea},
+ {0xf0700456, 0x6fb3}, {0xf274f175, 0x3b5}, {0xf2a9730b, 0x3a8},
+ {0xf3d463c2, 0x3a4}, {0xf52a70a3, 0xc42e}, {0xf5693147, 0x6fb3},
+ {0xf637e157, 0x478}, {0xfc213f3a, 0x2717}, {0xff654d14, 0x3b5},
+};
+FX_WORD FX_GetCodePageFromStringA(const FX_CHAR* pStr, int32_t iLength) {
+ FXSYS_assert(pStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_strlen(pStr);
+ }
+ if (iLength == 0) {
+ return 0xFFFF;
+ }
+ uint32_t uHash = FX_HashCode_String_GetA(pStr, iLength, TRUE);
+ int32_t iStart = 0, iMid;
+ int32_t iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1;
+ FXSYS_assert(iEnd >= 0);
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_STR2CPHASH& cp = g_FXCPHashTable[iMid];
+ if (uHash == cp.uHash) {
+ return (FX_WORD)cp.uCodePage;
+ } else if (uHash < cp.uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+FX_WORD FX_GetCodePageFormStringW(const FX_WCHAR* pStr, int32_t iLength) {
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pStr);
+ }
+ if (iLength == 0) {
+ return 0xFFFF;
+ }
+ CFX_ByteString csStr;
+ FX_CHAR* pBuf = csStr.GetBuffer(iLength + 1);
+ for (int32_t i = 0; i < iLength; ++i) {
+ *pBuf++ = (FX_CHAR)*pStr++;
+ }
+ csStr.ReleaseBuffer(iLength);
+ return FX_GetCodePageFromStringA(csStr, iLength);
+}
diff --git a/xfa/src/fgas/src/crt/fx_encode.cpp b/xfa/src/fgas/src/crt/fx_encode.cpp
index f2c5acb1c1..5c5d547eab 100644
--- a/xfa/src/fgas/src/crt/fx_encode.cpp
+++ b/xfa/src/fgas/src/crt/fx_encode.cpp
@@ -1,192 +1,192 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-void FX_SwapByteOrder(FX_WCHAR* pStr, int32_t iLength) {
- FXSYS_assert(pStr != NULL);
- if (iLength < 0) {
- iLength = FXSYS_wcslen(pStr);
- }
- FX_WORD wch;
- if (sizeof(FX_WCHAR) > 2) {
- while (iLength-- > 0) {
- wch = (FX_WORD)*pStr;
- wch = (wch >> 8) | (wch << 8);
- wch &= 0x00FF;
- *pStr++ = wch;
- }
- } else {
- while (iLength-- > 0) {
- wch = (FX_WORD)*pStr;
- wch = (wch >> 8) | (wch << 8);
- *pStr++ = wch;
- }
- }
-}
-void FX_SwapByteOrderCopy(const FX_WCHAR* pSrc,
- FX_WCHAR* pDst,
- int32_t iLength) {
- FXSYS_assert(pSrc != NULL && pDst != NULL);
- if (iLength < 0) {
- iLength = FXSYS_wcslen(pSrc);
- }
- FX_WORD wch;
- if (sizeof(FX_WCHAR) > 2) {
- while (iLength-- > 0) {
- wch = (FX_WORD)*pSrc++;
- wch = (wch >> 8) | (wch << 8);
- wch &= 0x00FF;
- *pDst++ = wch;
- }
- } else {
- while (iLength-- > 0) {
- wch = (FX_WORD)*pSrc++;
- wch = (wch >> 8) | (wch << 8);
- *pDst++ = wch;
- }
- }
-}
-void FX_UTF16ToWChar(void* pBuffer, int32_t iLength) {
- FXSYS_assert(pBuffer != NULL && iLength > 0);
- if (sizeof(FX_WCHAR) == 2) {
- return;
- }
- FX_WORD* pSrc = (FX_WORD*)pBuffer;
- FX_WCHAR* pDst = (FX_WCHAR*)pBuffer;
- while (--iLength >= 0) {
- pDst[iLength] = (FX_WCHAR)pSrc[iLength];
- }
-}
-void FX_UTF16ToWCharCopy(const FX_WORD* pUTF16,
- FX_WCHAR* pWChar,
- int32_t iLength) {
- FXSYS_assert(pUTF16 != NULL && pWChar != NULL && iLength > 0);
- if (sizeof(FX_WCHAR) == 2) {
- FXSYS_memcpy(pWChar, pUTF16, iLength * sizeof(FX_WCHAR));
- } else {
- while (--iLength >= 0) {
- pWChar[iLength] = (FX_WCHAR)pUTF16[iLength];
- }
- }
-}
-void FX_WCharToUTF16(void* pBuffer, int32_t iLength) {
- FXSYS_assert(pBuffer != NULL && iLength > 0);
- if (sizeof(FX_WCHAR) == 2) {
- return;
- }
- const FX_WCHAR* pSrc = (const FX_WCHAR*)pBuffer;
- FX_WORD* pDst = (FX_WORD*)pBuffer;
- while (--iLength >= 0) {
- *pDst++ = (FX_WORD)*pSrc++;
- }
-}
-void FX_WCharToUTF16Copy(const FX_WCHAR* pWChar,
- FX_WORD* pUTF16,
- int32_t iLength) {
- FXSYS_assert(pWChar != NULL && pUTF16 != NULL && iLength > 0);
- if (sizeof(FX_WCHAR) == 2) {
- FXSYS_memcpy(pUTF16, pWChar, iLength * sizeof(FX_WCHAR));
- } else {
- while (--iLength >= 0) {
- *pUTF16++ = (FX_WORD)*pWChar++;
- }
- }
-}
-inline FX_DWORD FX_DWordFromBytes(const uint8_t* pStr) {
- return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]);
-}
-inline FX_WORD FX_WordFromBytes(const uint8_t* pStr) {
- return (pStr[1] << 8 | pStr[0]);
-}
-int32_t FX_DecodeString(FX_WORD wCodePage,
- const FX_CHAR* pSrc,
- int32_t* pSrcLen,
- FX_WCHAR* pDst,
- int32_t* pDstLen,
- FX_BOOL bErrBreak) {
- if (wCodePage == FX_CODEPAGE_UTF8) {
- return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen);
- }
- return -1;
-}
-int32_t FX_UTF8Decode(const FX_CHAR* pSrc,
- int32_t* pSrcLen,
- FX_WCHAR* pDst,
- int32_t* pDstLen) {
- if (pSrcLen == NULL || pDstLen == NULL) {
- return -1;
- }
- int32_t iSrcLen = *pSrcLen;
- if (iSrcLen < 1) {
- *pSrcLen = *pDstLen = 0;
- return 1;
- }
- int32_t iDstLen = *pDstLen;
- FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0);
- FX_DWORD dwCode = 0;
- int32_t iPending = 0;
- int32_t iSrcNum = 0, iDstNum = 0;
- int32_t k = 0;
- int32_t iIndex = 0;
- k = 1;
- while (iIndex < iSrcLen) {
- uint8_t byte = (uint8_t) * (pSrc + iIndex);
- if (byte < 0x80) {
- iPending = 0;
- k = 1;
- iDstNum++;
- iSrcNum += k;
- if (bValidDst) {
- *pDst++ = byte;
- if (iDstNum >= iDstLen) {
- break;
- }
- }
- } else if (byte < 0xc0) {
- if (iPending < 1) {
- break;
- }
- iPending--;
- dwCode |= (byte & 0x3f) << (iPending * 6);
- if (iPending == 0) {
- iDstNum++;
- iSrcNum += k;
- if (bValidDst) {
- *pDst++ = dwCode;
- if (iDstNum >= iDstLen) {
- break;
- }
- }
- }
- } else if (byte < 0xe0) {
- iPending = 1;
- k = 2;
- dwCode = (byte & 0x1f) << 6;
- } else if (byte < 0xf0) {
- iPending = 2;
- k = 3;
- dwCode = (byte & 0x0f) << 12;
- } else if (byte < 0xf8) {
- iPending = 3;
- k = 4;
- dwCode = (byte & 0x07) << 18;
- } else if (byte < 0xfc) {
- iPending = 4;
- k = 5;
- dwCode = (byte & 0x03) << 24;
- } else if (byte < 0xfe) {
- iPending = 5;
- k = 6;
- dwCode = (byte & 0x01) << 30;
- } else {
- break;
- }
- iIndex++;
- }
- *pSrcLen = iSrcNum;
- *pDstLen = iDstNum;
- return 1;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+void FX_SwapByteOrder(FX_WCHAR* pStr, int32_t iLength) {
+ FXSYS_assert(pStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pStr);
+ }
+ FX_WORD wch;
+ if (sizeof(FX_WCHAR) > 2) {
+ while (iLength-- > 0) {
+ wch = (FX_WORD)*pStr;
+ wch = (wch >> 8) | (wch << 8);
+ wch &= 0x00FF;
+ *pStr++ = wch;
+ }
+ } else {
+ while (iLength-- > 0) {
+ wch = (FX_WORD)*pStr;
+ wch = (wch >> 8) | (wch << 8);
+ *pStr++ = wch;
+ }
+ }
+}
+void FX_SwapByteOrderCopy(const FX_WCHAR* pSrc,
+ FX_WCHAR* pDst,
+ int32_t iLength) {
+ FXSYS_assert(pSrc != NULL && pDst != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pSrc);
+ }
+ FX_WORD wch;
+ if (sizeof(FX_WCHAR) > 2) {
+ while (iLength-- > 0) {
+ wch = (FX_WORD)*pSrc++;
+ wch = (wch >> 8) | (wch << 8);
+ wch &= 0x00FF;
+ *pDst++ = wch;
+ }
+ } else {
+ while (iLength-- > 0) {
+ wch = (FX_WORD)*pSrc++;
+ wch = (wch >> 8) | (wch << 8);
+ *pDst++ = wch;
+ }
+ }
+}
+void FX_UTF16ToWChar(void* pBuffer, int32_t iLength) {
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ return;
+ }
+ FX_WORD* pSrc = (FX_WORD*)pBuffer;
+ FX_WCHAR* pDst = (FX_WCHAR*)pBuffer;
+ while (--iLength >= 0) {
+ pDst[iLength] = (FX_WCHAR)pSrc[iLength];
+ }
+}
+void FX_UTF16ToWCharCopy(const FX_WORD* pUTF16,
+ FX_WCHAR* pWChar,
+ int32_t iLength) {
+ FXSYS_assert(pUTF16 != NULL && pWChar != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ FXSYS_memcpy(pWChar, pUTF16, iLength * sizeof(FX_WCHAR));
+ } else {
+ while (--iLength >= 0) {
+ pWChar[iLength] = (FX_WCHAR)pUTF16[iLength];
+ }
+ }
+}
+void FX_WCharToUTF16(void* pBuffer, int32_t iLength) {
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ return;
+ }
+ const FX_WCHAR* pSrc = (const FX_WCHAR*)pBuffer;
+ FX_WORD* pDst = (FX_WORD*)pBuffer;
+ while (--iLength >= 0) {
+ *pDst++ = (FX_WORD)*pSrc++;
+ }
+}
+void FX_WCharToUTF16Copy(const FX_WCHAR* pWChar,
+ FX_WORD* pUTF16,
+ int32_t iLength) {
+ FXSYS_assert(pWChar != NULL && pUTF16 != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ FXSYS_memcpy(pUTF16, pWChar, iLength * sizeof(FX_WCHAR));
+ } else {
+ while (--iLength >= 0) {
+ *pUTF16++ = (FX_WORD)*pWChar++;
+ }
+ }
+}
+inline FX_DWORD FX_DWordFromBytes(const uint8_t* pStr) {
+ return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]);
+}
+inline FX_WORD FX_WordFromBytes(const uint8_t* pStr) {
+ return (pStr[1] << 8 | pStr[0]);
+}
+int32_t FX_DecodeString(FX_WORD wCodePage,
+ const FX_CHAR* pSrc,
+ int32_t* pSrcLen,
+ FX_WCHAR* pDst,
+ int32_t* pDstLen,
+ FX_BOOL bErrBreak) {
+ if (wCodePage == FX_CODEPAGE_UTF8) {
+ return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen);
+ }
+ return -1;
+}
+int32_t FX_UTF8Decode(const FX_CHAR* pSrc,
+ int32_t* pSrcLen,
+ FX_WCHAR* pDst,
+ int32_t* pDstLen) {
+ if (pSrcLen == NULL || pDstLen == NULL) {
+ return -1;
+ }
+ int32_t iSrcLen = *pSrcLen;
+ if (iSrcLen < 1) {
+ *pSrcLen = *pDstLen = 0;
+ return 1;
+ }
+ int32_t iDstLen = *pDstLen;
+ FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0);
+ FX_DWORD dwCode = 0;
+ int32_t iPending = 0;
+ int32_t iSrcNum = 0, iDstNum = 0;
+ int32_t k = 0;
+ int32_t iIndex = 0;
+ k = 1;
+ while (iIndex < iSrcLen) {
+ uint8_t byte = (uint8_t) * (pSrc + iIndex);
+ if (byte < 0x80) {
+ iPending = 0;
+ k = 1;
+ iDstNum++;
+ iSrcNum += k;
+ if (bValidDst) {
+ *pDst++ = byte;
+ if (iDstNum >= iDstLen) {
+ break;
+ }
+ }
+ } else if (byte < 0xc0) {
+ if (iPending < 1) {
+ break;
+ }
+ iPending--;
+ dwCode |= (byte & 0x3f) << (iPending * 6);
+ if (iPending == 0) {
+ iDstNum++;
+ iSrcNum += k;
+ if (bValidDst) {
+ *pDst++ = dwCode;
+ if (iDstNum >= iDstLen) {
+ break;
+ }
+ }
+ }
+ } else if (byte < 0xe0) {
+ iPending = 1;
+ k = 2;
+ dwCode = (byte & 0x1f) << 6;
+ } else if (byte < 0xf0) {
+ iPending = 2;
+ k = 3;
+ dwCode = (byte & 0x0f) << 12;
+ } else if (byte < 0xf8) {
+ iPending = 3;
+ k = 4;
+ dwCode = (byte & 0x07) << 18;
+ } else if (byte < 0xfc) {
+ iPending = 4;
+ k = 5;
+ dwCode = (byte & 0x03) << 24;
+ } else if (byte < 0xfe) {
+ iPending = 5;
+ k = 6;
+ dwCode = (byte & 0x01) << 30;
+ } else {
+ break;
+ }
+ iIndex++;
+ }
+ *pSrcLen = iSrcNum;
+ *pDstLen = iDstNum;
+ return 1;
+}
diff --git a/xfa/src/fgas/src/crt/fx_memory.cpp b/xfa/src/fgas/src/crt/fx_memory.cpp
index 0f17dc8a7e..497512d8e2 100644
--- a/xfa/src/fgas/src/crt/fx_memory.cpp
+++ b/xfa/src/fgas/src/crt/fx_memory.cpp
@@ -1,324 +1,324 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_memory.h"
-#define FX_4BYTEALIGN(size) (((size) + 3) / 4 * 4)
-IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType,
- size_t chunkSize,
- size_t blockSize) {
- switch (eType) {
-#ifndef _FXEMB
- case FX_ALLOCTYPE_Dynamic:
- return new CFX_DynamicStore(chunkSize);
-#endif
- case FX_ALLOCTYPE_Default:
- return new CFX_DefStore();
- case FX_ALLOCTYPE_Static:
- return new CFX_StaticStore(chunkSize);
- case FX_ALLOCTYPE_Fixed:
- return new CFX_FixedStore(blockSize, chunkSize);
- default:
- return NULL;
- }
-}
-CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize)
- : m_iAllocatedSize(0),
- m_iDefChunkSize(iDefChunkSize),
- m_pChunk(NULL),
- m_pLastChunk(NULL) {
- FXSYS_assert(m_iDefChunkSize != 0);
-}
-CFX_StaticStore::~CFX_StaticStore() {
- FX_LPSTATICSTORECHUNK pChunk, pNext;
- pChunk = m_pChunk;
- while (pChunk != NULL) {
- pNext = pChunk->pNextChunk;
- FX_Free(pChunk);
- pChunk = pNext;
- }
-}
-FX_LPSTATICSTORECHUNK CFX_StaticStore::AllocChunk(size_t size) {
- FXSYS_assert(size != 0);
- FX_LPSTATICSTORECHUNK pChunk = (FX_LPSTATICSTORECHUNK)FX_Alloc(
- uint8_t, sizeof(FX_STATICSTORECHUNK) + size);
- pChunk->iChunkSize = size;
- pChunk->iFreeSize = size;
- pChunk->pNextChunk = NULL;
- if (m_pLastChunk == NULL) {
- m_pChunk = pChunk;
- } else {
- m_pLastChunk->pNextChunk = pChunk;
- }
- m_pLastChunk = pChunk;
- return pChunk;
-}
-FX_LPSTATICSTORECHUNK CFX_StaticStore::FindChunk(size_t size) {
- FXSYS_assert(size != 0);
- if (m_pLastChunk == NULL || m_pLastChunk->iFreeSize < size) {
- return AllocChunk(std::max(m_iDefChunkSize, size));
- }
- return m_pLastChunk;
-}
-void* CFX_StaticStore::Alloc(size_t size) {
- size = FX_4BYTEALIGN(size);
- FXSYS_assert(size != 0);
- FX_LPSTATICSTORECHUNK pChunk = FindChunk(size);
- FXSYS_assert(pChunk != NULL && pChunk->iFreeSize >= size);
- uint8_t* p = (uint8_t*)pChunk;
- p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize;
- pChunk->iFreeSize -= size;
- m_iAllocatedSize += size;
- return p;
-}
-size_t CFX_StaticStore::SetDefChunkSize(size_t size) {
- FXSYS_assert(size != 0);
- size_t v = m_iDefChunkSize;
- m_iDefChunkSize = size;
- return v;
-}
-CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk)
- : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)),
- m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)),
- m_pChunk(NULL) {
- FXSYS_assert(m_iBlockSize != 0 && m_iDefChunkSize != 0);
-}
-CFX_FixedStore::~CFX_FixedStore() {
- FX_LPFIXEDSTORECHUNK pChunk, pNext;
- pChunk = m_pChunk;
- while (pChunk != NULL) {
- pNext = pChunk->pNextChunk;
- FX_Free(pChunk);
- pChunk = pNext;
- }
-}
-FX_LPFIXEDSTORECHUNK CFX_FixedStore::AllocChunk() {
- int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize +
- m_iBlockSize * m_iDefChunkSize;
- FX_LPFIXEDSTORECHUNK pChunk =
- (FX_LPFIXEDSTORECHUNK)FX_Alloc(uint8_t, iTotalSize);
- if (pChunk == NULL) {
- return NULL;
- }
- FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize);
- pChunk->pNextChunk = m_pChunk;
- pChunk->iChunkSize = m_iDefChunkSize;
- pChunk->iFreeNum = m_iDefChunkSize;
- m_pChunk = pChunk;
- return pChunk;
-}
-void* CFX_FixedStore::Alloc(size_t size) {
- if (size > m_iBlockSize) {
- return NULL;
- }
- FX_LPFIXEDSTORECHUNK pChunk = m_pChunk;
- while (pChunk != NULL) {
- if (pChunk->iFreeNum > 0) {
- break;
- }
- pChunk = pChunk->pNextChunk;
- }
- if (pChunk == NULL) {
- pChunk = AllocChunk();
- }
- FXSYS_assert(pChunk != NULL);
- uint8_t* pFlags = pChunk->FirstFlag();
- size_t i = 0;
- for (; i < pChunk->iChunkSize; i++)
- if (pFlags[i] == 0) {
- break;
- }
- FXSYS_assert(i < pChunk->iChunkSize);
- pFlags[i] = 1;
- pChunk->iFreeNum--;
- return pChunk->FirstBlock() + i * m_iBlockSize;
-}
-void CFX_FixedStore::Free(void* pBlock) {
- FXSYS_assert(pBlock != NULL);
- FX_LPFIXEDSTORECHUNK pPrior, pChunk;
- pPrior = NULL, pChunk = m_pChunk;
- uint8_t* pStart = NULL;
- uint8_t* pEnd;
- while (pChunk != NULL) {
- pStart = pChunk->FirstBlock();
- if (pBlock >= pStart) {
- pEnd = pStart + m_iBlockSize * pChunk->iChunkSize;
- if (pBlock < pEnd) {
- break;
- }
- }
- pPrior = pChunk, pChunk = pChunk->pNextChunk;
- }
- FXSYS_assert(pChunk != NULL);
- size_t iPos = ((uint8_t*)pBlock - pStart) / m_iBlockSize;
- FXSYS_assert(iPos < pChunk->iChunkSize);
- uint8_t* pFlags = pChunk->FirstFlag();
- if (pFlags[iPos] == 0) {
- return;
- }
- pFlags[iPos] = 0;
- pChunk->iFreeNum++;
- if (pChunk->iFreeNum == pChunk->iChunkSize) {
- if (pPrior == NULL) {
- m_pChunk = pChunk->pNextChunk;
- } else {
- pPrior->pNextChunk = pChunk->pNextChunk;
- }
- FX_Free(pChunk);
- }
-}
-size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize) {
- FXSYS_assert(iChunkSize != 0);
- size_t v = m_iDefChunkSize;
- m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize);
- return v;
-}
-#ifndef _FXEMB
-CFX_DynamicStore::CFX_DynamicStore(size_t iDefChunkSize)
- : m_iDefChunkSize(iDefChunkSize), m_pChunk(NULL) {
- FXSYS_assert(m_iDefChunkSize != 0);
-}
-CFX_DynamicStore::~CFX_DynamicStore() {
- FX_LPDYNAMICSTORECHUNK pChunk, pNext;
- pChunk = m_pChunk;
- while (pChunk != NULL) {
- pNext = pChunk->pNextChunk;
- FX_Free(pChunk);
- pChunk = pNext;
- }
-}
-FX_LPDYNAMICSTORECHUNK CFX_DynamicStore::AllocChunk(size_t size) {
- FXSYS_assert(size != 0);
- FX_LPDYNAMICSTORECHUNK pChunk = (FX_LPDYNAMICSTORECHUNK)FX_Alloc(
- uint8_t,
- sizeof(FX_DYNAMICSTORECHUNK) + sizeof(FX_DYNAMICSTOREBLOCK) * 2 + size);
- if (pChunk == NULL) {
- return NULL;
- }
- pChunk->iChunkSize = size;
- pChunk->iFreeSize = size;
- FX_LPDYNAMICSTOREBLOCK pBlock = pChunk->FirstBlock();
- pBlock->iBlockSize = size;
- pBlock->bUsed = FALSE;
- pBlock = pBlock->NextBlock();
- pBlock->iBlockSize = 0;
- pBlock->bUsed = TRUE;
- if (m_pChunk != NULL && size >= m_iDefChunkSize) {
- FX_LPDYNAMICSTORECHUNK pLast = m_pChunk;
- while (pLast->pNextChunk != NULL) {
- pLast = pLast->pNextChunk;
- }
- pLast->pNextChunk = pChunk;
- pChunk->pNextChunk = NULL;
- } else {
- pChunk->pNextChunk = m_pChunk;
- m_pChunk = pChunk;
- }
- return pChunk;
-}
-void* CFX_DynamicStore::Alloc(size_t size) {
- size = FX_4BYTEALIGN(size);
- FXSYS_assert(size != 0);
- FX_LPDYNAMICSTORECHUNK pChunk = m_pChunk;
- FX_LPDYNAMICSTOREBLOCK pBlock = NULL;
- while (pChunk != NULL) {
- if (pChunk->iFreeSize >= size) {
- pBlock = pChunk->FirstBlock();
- FX_BOOL bFind = FALSE;
- while (pBlock->iBlockSize != 0) {
- if (!pBlock->bUsed && pBlock->iBlockSize >= size) {
- bFind = TRUE;
- break;
- }
- pBlock = pBlock->NextBlock();
- }
- if (bFind) {
- break;
- }
- }
- pChunk = pChunk->pNextChunk;
- }
- if (pChunk == NULL) {
- pChunk = AllocChunk(std::max(m_iDefChunkSize, size));
- pBlock = pChunk->FirstBlock();
- }
- FXSYS_assert(pChunk != NULL && pBlock != NULL);
- size_t m = size + sizeof(FX_DYNAMICSTOREBLOCK);
- pBlock->bUsed = TRUE;
- if (pBlock->iBlockSize > m) {
- size_t n = pBlock->iBlockSize;
- pBlock->iBlockSize = size;
- FX_LPDYNAMICSTOREBLOCK pNextBlock = pBlock->NextBlock();
- pNextBlock->bUsed = FALSE;
- pNextBlock->iBlockSize = n - size - sizeof(FX_DYNAMICSTOREBLOCK);
- pChunk->iFreeSize -= size + sizeof(FX_DYNAMICSTOREBLOCK);
- } else {
- pChunk->iFreeSize -= pBlock->iBlockSize;
- }
- return pBlock->Data();
-}
-void CFX_DynamicStore::Free(void* pBlock) {
- FXSYS_assert(pBlock != NULL);
- FX_LPDYNAMICSTORECHUNK pPriorChunk, pChunk;
- pPriorChunk = NULL, pChunk = m_pChunk;
- while (pChunk != NULL) {
- if (pBlock > pChunk &&
- pBlock <= ((uint8_t*)pChunk + sizeof(FX_DYNAMICSTORECHUNK) +
- pChunk->iChunkSize)) {
- break;
- }
- pPriorChunk = pChunk, pChunk = pChunk->pNextChunk;
- }
- FXSYS_assert(pChunk != NULL);
- FX_LPDYNAMICSTOREBLOCK pPriorBlock, pFindBlock;
- pPriorBlock = NULL, pFindBlock = pChunk->FirstBlock();
- while (pFindBlock->iBlockSize != 0) {
- if (pBlock == (void*)pFindBlock->Data()) {
- break;
- }
- pPriorBlock = pFindBlock;
- pFindBlock = pFindBlock->NextBlock();
- }
- FXSYS_assert(pFindBlock->iBlockSize != 0 && pFindBlock->bUsed &&
- pBlock == (void*)pFindBlock->Data());
- pFindBlock->bUsed = FALSE;
- pChunk->iFreeSize += pFindBlock->iBlockSize;
- if (pPriorBlock == NULL) {
- pPriorBlock = pChunk->FirstBlock();
- } else if (pPriorBlock->bUsed) {
- pPriorBlock = pFindBlock;
- }
- pFindBlock = pPriorBlock;
- size_t sizeFree = 0;
- size_t sizeBlock = 0;
- while (pFindBlock->iBlockSize != 0 && !pFindBlock->bUsed) {
- if (pFindBlock != pPriorBlock) {
- sizeFree += sizeof(FX_DYNAMICSTOREBLOCK);
- sizeBlock += sizeof(FX_DYNAMICSTOREBLOCK);
- }
- sizeBlock += pFindBlock->iBlockSize;
- pFindBlock = pFindBlock->NextBlock();
- }
- pPriorBlock->iBlockSize = sizeBlock;
- pChunk->iFreeSize += sizeFree;
- if (pChunk->iFreeSize == pChunk->iChunkSize) {
- if (pPriorChunk == NULL) {
- m_pChunk = pChunk->pNextChunk;
- } else {
- pPriorChunk->pNextChunk = pChunk->pNextChunk;
- }
- FX_Free(pChunk);
- }
-}
-size_t CFX_DynamicStore::SetDefChunkSize(size_t size) {
- FXSYS_assert(size != 0);
- size_t v = m_iDefChunkSize;
- m_iDefChunkSize = size;
- return v;
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_memory.h"
+#define FX_4BYTEALIGN(size) (((size) + 3) / 4 * 4)
+IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType,
+ size_t chunkSize,
+ size_t blockSize) {
+ switch (eType) {
+#ifndef _FXEMB
+ case FX_ALLOCTYPE_Dynamic:
+ return new CFX_DynamicStore(chunkSize);
+#endif
+ case FX_ALLOCTYPE_Default:
+ return new CFX_DefStore();
+ case FX_ALLOCTYPE_Static:
+ return new CFX_StaticStore(chunkSize);
+ case FX_ALLOCTYPE_Fixed:
+ return new CFX_FixedStore(blockSize, chunkSize);
+ default:
+ return NULL;
+ }
+}
+CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize)
+ : m_iAllocatedSize(0),
+ m_iDefChunkSize(iDefChunkSize),
+ m_pChunk(NULL),
+ m_pLastChunk(NULL) {
+ FXSYS_assert(m_iDefChunkSize != 0);
+}
+CFX_StaticStore::~CFX_StaticStore() {
+ FX_LPSTATICSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPSTATICSTORECHUNK CFX_StaticStore::AllocChunk(size_t size) {
+ FXSYS_assert(size != 0);
+ FX_LPSTATICSTORECHUNK pChunk = (FX_LPSTATICSTORECHUNK)FX_Alloc(
+ uint8_t, sizeof(FX_STATICSTORECHUNK) + size);
+ pChunk->iChunkSize = size;
+ pChunk->iFreeSize = size;
+ pChunk->pNextChunk = NULL;
+ if (m_pLastChunk == NULL) {
+ m_pChunk = pChunk;
+ } else {
+ m_pLastChunk->pNextChunk = pChunk;
+ }
+ m_pLastChunk = pChunk;
+ return pChunk;
+}
+FX_LPSTATICSTORECHUNK CFX_StaticStore::FindChunk(size_t size) {
+ FXSYS_assert(size != 0);
+ if (m_pLastChunk == NULL || m_pLastChunk->iFreeSize < size) {
+ return AllocChunk(std::max(m_iDefChunkSize, size));
+ }
+ return m_pLastChunk;
+}
+void* CFX_StaticStore::Alloc(size_t size) {
+ size = FX_4BYTEALIGN(size);
+ FXSYS_assert(size != 0);
+ FX_LPSTATICSTORECHUNK pChunk = FindChunk(size);
+ FXSYS_assert(pChunk != NULL && pChunk->iFreeSize >= size);
+ uint8_t* p = (uint8_t*)pChunk;
+ p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize;
+ pChunk->iFreeSize -= size;
+ m_iAllocatedSize += size;
+ return p;
+}
+size_t CFX_StaticStore::SetDefChunkSize(size_t size) {
+ FXSYS_assert(size != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = size;
+ return v;
+}
+CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk)
+ : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)),
+ m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)),
+ m_pChunk(NULL) {
+ FXSYS_assert(m_iBlockSize != 0 && m_iDefChunkSize != 0);
+}
+CFX_FixedStore::~CFX_FixedStore() {
+ FX_LPFIXEDSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPFIXEDSTORECHUNK CFX_FixedStore::AllocChunk() {
+ int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize +
+ m_iBlockSize * m_iDefChunkSize;
+ FX_LPFIXEDSTORECHUNK pChunk =
+ (FX_LPFIXEDSTORECHUNK)FX_Alloc(uint8_t, iTotalSize);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize);
+ pChunk->pNextChunk = m_pChunk;
+ pChunk->iChunkSize = m_iDefChunkSize;
+ pChunk->iFreeNum = m_iDefChunkSize;
+ m_pChunk = pChunk;
+ return pChunk;
+}
+void* CFX_FixedStore::Alloc(size_t size) {
+ if (size > m_iBlockSize) {
+ return NULL;
+ }
+ FX_LPFIXEDSTORECHUNK pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ if (pChunk->iFreeNum > 0) {
+ break;
+ }
+ pChunk = pChunk->pNextChunk;
+ }
+ if (pChunk == NULL) {
+ pChunk = AllocChunk();
+ }
+ FXSYS_assert(pChunk != NULL);
+ uint8_t* pFlags = pChunk->FirstFlag();
+ size_t i = 0;
+ for (; i < pChunk->iChunkSize; i++)
+ if (pFlags[i] == 0) {
+ break;
+ }
+ FXSYS_assert(i < pChunk->iChunkSize);
+ pFlags[i] = 1;
+ pChunk->iFreeNum--;
+ return pChunk->FirstBlock() + i * m_iBlockSize;
+}
+void CFX_FixedStore::Free(void* pBlock) {
+ FXSYS_assert(pBlock != NULL);
+ FX_LPFIXEDSTORECHUNK pPrior, pChunk;
+ pPrior = NULL, pChunk = m_pChunk;
+ uint8_t* pStart = NULL;
+ uint8_t* pEnd;
+ while (pChunk != NULL) {
+ pStart = pChunk->FirstBlock();
+ if (pBlock >= pStart) {
+ pEnd = pStart + m_iBlockSize * pChunk->iChunkSize;
+ if (pBlock < pEnd) {
+ break;
+ }
+ }
+ pPrior = pChunk, pChunk = pChunk->pNextChunk;
+ }
+ FXSYS_assert(pChunk != NULL);
+ size_t iPos = ((uint8_t*)pBlock - pStart) / m_iBlockSize;
+ FXSYS_assert(iPos < pChunk->iChunkSize);
+ uint8_t* pFlags = pChunk->FirstFlag();
+ if (pFlags[iPos] == 0) {
+ return;
+ }
+ pFlags[iPos] = 0;
+ pChunk->iFreeNum++;
+ if (pChunk->iFreeNum == pChunk->iChunkSize) {
+ if (pPrior == NULL) {
+ m_pChunk = pChunk->pNextChunk;
+ } else {
+ pPrior->pNextChunk = pChunk->pNextChunk;
+ }
+ FX_Free(pChunk);
+ }
+}
+size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize) {
+ FXSYS_assert(iChunkSize != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize);
+ return v;
+}
+#ifndef _FXEMB
+CFX_DynamicStore::CFX_DynamicStore(size_t iDefChunkSize)
+ : m_iDefChunkSize(iDefChunkSize), m_pChunk(NULL) {
+ FXSYS_assert(m_iDefChunkSize != 0);
+}
+CFX_DynamicStore::~CFX_DynamicStore() {
+ FX_LPDYNAMICSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPDYNAMICSTORECHUNK CFX_DynamicStore::AllocChunk(size_t size) {
+ FXSYS_assert(size != 0);
+ FX_LPDYNAMICSTORECHUNK pChunk = (FX_LPDYNAMICSTORECHUNK)FX_Alloc(
+ uint8_t,
+ sizeof(FX_DYNAMICSTORECHUNK) + sizeof(FX_DYNAMICSTOREBLOCK) * 2 + size);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ pChunk->iChunkSize = size;
+ pChunk->iFreeSize = size;
+ FX_LPDYNAMICSTOREBLOCK pBlock = pChunk->FirstBlock();
+ pBlock->iBlockSize = size;
+ pBlock->bUsed = FALSE;
+ pBlock = pBlock->NextBlock();
+ pBlock->iBlockSize = 0;
+ pBlock->bUsed = TRUE;
+ if (m_pChunk != NULL && size >= m_iDefChunkSize) {
+ FX_LPDYNAMICSTORECHUNK pLast = m_pChunk;
+ while (pLast->pNextChunk != NULL) {
+ pLast = pLast->pNextChunk;
+ }
+ pLast->pNextChunk = pChunk;
+ pChunk->pNextChunk = NULL;
+ } else {
+ pChunk->pNextChunk = m_pChunk;
+ m_pChunk = pChunk;
+ }
+ return pChunk;
+}
+void* CFX_DynamicStore::Alloc(size_t size) {
+ size = FX_4BYTEALIGN(size);
+ FXSYS_assert(size != 0);
+ FX_LPDYNAMICSTORECHUNK pChunk = m_pChunk;
+ FX_LPDYNAMICSTOREBLOCK pBlock = NULL;
+ while (pChunk != NULL) {
+ if (pChunk->iFreeSize >= size) {
+ pBlock = pChunk->FirstBlock();
+ FX_BOOL bFind = FALSE;
+ while (pBlock->iBlockSize != 0) {
+ if (!pBlock->bUsed && pBlock->iBlockSize >= size) {
+ bFind = TRUE;
+ break;
+ }
+ pBlock = pBlock->NextBlock();
+ }
+ if (bFind) {
+ break;
+ }
+ }
+ pChunk = pChunk->pNextChunk;
+ }
+ if (pChunk == NULL) {
+ pChunk = AllocChunk(std::max(m_iDefChunkSize, size));
+ pBlock = pChunk->FirstBlock();
+ }
+ FXSYS_assert(pChunk != NULL && pBlock != NULL);
+ size_t m = size + sizeof(FX_DYNAMICSTOREBLOCK);
+ pBlock->bUsed = TRUE;
+ if (pBlock->iBlockSize > m) {
+ size_t n = pBlock->iBlockSize;
+ pBlock->iBlockSize = size;
+ FX_LPDYNAMICSTOREBLOCK pNextBlock = pBlock->NextBlock();
+ pNextBlock->bUsed = FALSE;
+ pNextBlock->iBlockSize = n - size - sizeof(FX_DYNAMICSTOREBLOCK);
+ pChunk->iFreeSize -= size + sizeof(FX_DYNAMICSTOREBLOCK);
+ } else {
+ pChunk->iFreeSize -= pBlock->iBlockSize;
+ }
+ return pBlock->Data();
+}
+void CFX_DynamicStore::Free(void* pBlock) {
+ FXSYS_assert(pBlock != NULL);
+ FX_LPDYNAMICSTORECHUNK pPriorChunk, pChunk;
+ pPriorChunk = NULL, pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ if (pBlock > pChunk &&
+ pBlock <= ((uint8_t*)pChunk + sizeof(FX_DYNAMICSTORECHUNK) +
+ pChunk->iChunkSize)) {
+ break;
+ }
+ pPriorChunk = pChunk, pChunk = pChunk->pNextChunk;
+ }
+ FXSYS_assert(pChunk != NULL);
+ FX_LPDYNAMICSTOREBLOCK pPriorBlock, pFindBlock;
+ pPriorBlock = NULL, pFindBlock = pChunk->FirstBlock();
+ while (pFindBlock->iBlockSize != 0) {
+ if (pBlock == (void*)pFindBlock->Data()) {
+ break;
+ }
+ pPriorBlock = pFindBlock;
+ pFindBlock = pFindBlock->NextBlock();
+ }
+ FXSYS_assert(pFindBlock->iBlockSize != 0 && pFindBlock->bUsed &&
+ pBlock == (void*)pFindBlock->Data());
+ pFindBlock->bUsed = FALSE;
+ pChunk->iFreeSize += pFindBlock->iBlockSize;
+ if (pPriorBlock == NULL) {
+ pPriorBlock = pChunk->FirstBlock();
+ } else if (pPriorBlock->bUsed) {
+ pPriorBlock = pFindBlock;
+ }
+ pFindBlock = pPriorBlock;
+ size_t sizeFree = 0;
+ size_t sizeBlock = 0;
+ while (pFindBlock->iBlockSize != 0 && !pFindBlock->bUsed) {
+ if (pFindBlock != pPriorBlock) {
+ sizeFree += sizeof(FX_DYNAMICSTOREBLOCK);
+ sizeBlock += sizeof(FX_DYNAMICSTOREBLOCK);
+ }
+ sizeBlock += pFindBlock->iBlockSize;
+ pFindBlock = pFindBlock->NextBlock();
+ }
+ pPriorBlock->iBlockSize = sizeBlock;
+ pChunk->iFreeSize += sizeFree;
+ if (pChunk->iFreeSize == pChunk->iChunkSize) {
+ if (pPriorChunk == NULL) {
+ m_pChunk = pChunk->pNextChunk;
+ } else {
+ pPriorChunk->pNextChunk = pChunk->pNextChunk;
+ }
+ FX_Free(pChunk);
+ }
+}
+size_t CFX_DynamicStore::SetDefChunkSize(size_t size) {
+ FXSYS_assert(size != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = size;
+ return v;
+}
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_memory.h b/xfa/src/fgas/src/crt/fx_memory.h
index 2f42773058..e181ce834d 100644
--- a/xfa/src/fgas/src/crt/fx_memory.h
+++ b/xfa/src/fgas/src/crt/fx_memory.h
@@ -1,135 +1,135 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_MEMORY_IMP
-#define _FX_MEMORY_IMP
-class CFX_DefStore;
-class CFX_StaticStore;
-class CFX_FixedStore;
-class CFX_DynamicStore;
-class CFX_DefStore : public IFX_MEMAllocator, public CFX_Target {
- public:
- CFX_DefStore() {}
- ~CFX_DefStore() {}
- virtual void Release() { delete this; }
- virtual void* Alloc(size_t size) { return FX_Alloc(uint8_t, size); }
- virtual void Free(void* pBlock) { FX_Free(pBlock); }
- virtual size_t GetBlockSize() const { return 0; }
- virtual size_t GetDefChunkSize() const { return 0; }
- virtual size_t SetDefChunkSize(size_t size) { return 0; }
- virtual size_t GetCurrentDataSize() const { return 0; }
-};
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(push, 1)
-#endif
-typedef struct _FX_STATICSTORECHUNK {
- _FX_STATICSTORECHUNK* pNextChunk;
- size_t iChunkSize;
- size_t iFreeSize;
-} FX_STATICSTORECHUNK, *FX_LPSTATICSTORECHUNK;
-typedef FX_STATICSTORECHUNK const* FX_LPCSTATICSTORECHUNK;
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(pop)
-#endif
-class CFX_StaticStore : public IFX_MEMAllocator, public CFX_Target {
- public:
- CFX_StaticStore(size_t iDefChunkSize = 4096);
- ~CFX_StaticStore();
- virtual void Release() { delete this; }
- virtual void* Alloc(size_t size);
- virtual void Free(void* pBlock) {}
- virtual size_t GetBlockSize() const { return 0; }
- virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
- virtual size_t SetDefChunkSize(size_t size);
- virtual size_t GetCurrentDataSize() const { return m_iAllocatedSize; }
-
- protected:
- size_t m_iAllocatedSize;
- size_t m_iDefChunkSize;
- FX_LPSTATICSTORECHUNK m_pChunk;
- FX_LPSTATICSTORECHUNK m_pLastChunk;
- FX_LPSTATICSTORECHUNK AllocChunk(size_t size);
- FX_LPSTATICSTORECHUNK FindChunk(size_t size);
-};
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(push, 1)
-#endif
-typedef struct _FX_FIXEDSTORECHUNK {
- uint8_t* FirstFlag() const {
- return (uint8_t*)this + sizeof(_FX_FIXEDSTORECHUNK);
- }
- uint8_t* FirstBlock() const { return FirstFlag() + iChunkSize; }
- _FX_FIXEDSTORECHUNK* pNextChunk;
- size_t iChunkSize;
- size_t iFreeNum;
-} FX_FIXEDSTORECHUNK, *FX_LPFIXEDSTORECHUNK;
-typedef FX_FIXEDSTORECHUNK const* FX_LPCFIXEDSTORECHUNK;
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(pop)
-#endif
-class CFX_FixedStore : public IFX_MEMAllocator, public CFX_Target {
- public:
- CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk);
- virtual ~CFX_FixedStore();
- virtual void Release() { delete this; }
- virtual void* Alloc(size_t size);
- virtual void Free(void* pBlock);
- virtual size_t GetBlockSize() const { return m_iBlockSize; }
- virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
- virtual size_t SetDefChunkSize(size_t iChunkSize);
- virtual size_t GetCurrentDataSize() const { return 0; }
-
- protected:
- size_t m_iBlockSize;
- size_t m_iDefChunkSize;
- FX_LPFIXEDSTORECHUNK m_pChunk;
- FX_LPFIXEDSTORECHUNK AllocChunk();
-};
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(push, 1)
-#endif
-typedef struct _FX_DYNAMICSTOREBLOCK {
- _FX_DYNAMICSTOREBLOCK* NextBlock() const {
- return (_FX_DYNAMICSTOREBLOCK*)(Data() + iBlockSize);
- }
- uint8_t* Data() const {
- return (uint8_t*)this + sizeof(_FX_DYNAMICSTOREBLOCK);
- }
- size_t iBlockSize;
- FX_BOOL bUsed;
-} FX_DYNAMICSTOREBLOCK, *FX_LPDYNAMICSTOREBLOCK;
-typedef FX_DYNAMICSTOREBLOCK const* FX_LPCDYNAMICSTOREBLOCK;
-typedef struct _FX_DYNAMICSTORECHUNK {
- FX_LPDYNAMICSTOREBLOCK FirstBlock() const {
- return (FX_LPDYNAMICSTOREBLOCK)((uint8_t*)this +
- sizeof(_FX_DYNAMICSTORECHUNK));
- }
- _FX_DYNAMICSTORECHUNK* pNextChunk;
- size_t iChunkSize;
- size_t iFreeSize;
-} FX_DYNAMICSTORECHUNK, *FX_LPDYNAMICSTORECHUNK;
-typedef FX_DYNAMICSTORECHUNK const* FX_LPCDYNAMICSTORECHUNK;
-#if _FX_OS_ != _FX_ANDROID_
-#pragma pack(pop)
-#endif
-class CFX_DynamicStore : public IFX_MEMAllocator, public CFX_Target {
- public:
- CFX_DynamicStore(size_t iDefChunkSize = 4096);
- virtual ~CFX_DynamicStore();
- virtual void Release() { delete this; }
- virtual void* Alloc(size_t size);
- virtual void Free(void* pBlock);
- virtual size_t GetBlockSize() const { return 0; }
- virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
- virtual size_t SetDefChunkSize(size_t size);
- virtual size_t GetCurrentDataSize() const { return 0; }
-
- protected:
- size_t m_iDefChunkSize;
- FX_LPDYNAMICSTORECHUNK m_pChunk;
- FX_LPDYNAMICSTORECHUNK AllocChunk(size_t size);
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_MEMORY_IMP
+#define _FX_MEMORY_IMP
+class CFX_DefStore;
+class CFX_StaticStore;
+class CFX_FixedStore;
+class CFX_DynamicStore;
+class CFX_DefStore : public IFX_MEMAllocator, public CFX_Target {
+ public:
+ CFX_DefStore() {}
+ ~CFX_DefStore() {}
+ virtual void Release() { delete this; }
+ virtual void* Alloc(size_t size) { return FX_Alloc(uint8_t, size); }
+ virtual void Free(void* pBlock) { FX_Free(pBlock); }
+ virtual size_t GetBlockSize() const { return 0; }
+ virtual size_t GetDefChunkSize() const { return 0; }
+ virtual size_t SetDefChunkSize(size_t size) { return 0; }
+ virtual size_t GetCurrentDataSize() const { return 0; }
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_STATICSTORECHUNK {
+ _FX_STATICSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeSize;
+} FX_STATICSTORECHUNK, *FX_LPSTATICSTORECHUNK;
+typedef FX_STATICSTORECHUNK const* FX_LPCSTATICSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_StaticStore : public IFX_MEMAllocator, public CFX_Target {
+ public:
+ CFX_StaticStore(size_t iDefChunkSize = 4096);
+ ~CFX_StaticStore();
+ virtual void Release() { delete this; }
+ virtual void* Alloc(size_t size);
+ virtual void Free(void* pBlock) {}
+ virtual size_t GetBlockSize() const { return 0; }
+ virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
+ virtual size_t SetDefChunkSize(size_t size);
+ virtual size_t GetCurrentDataSize() const { return m_iAllocatedSize; }
+
+ protected:
+ size_t m_iAllocatedSize;
+ size_t m_iDefChunkSize;
+ FX_LPSTATICSTORECHUNK m_pChunk;
+ FX_LPSTATICSTORECHUNK m_pLastChunk;
+ FX_LPSTATICSTORECHUNK AllocChunk(size_t size);
+ FX_LPSTATICSTORECHUNK FindChunk(size_t size);
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_FIXEDSTORECHUNK {
+ uint8_t* FirstFlag() const {
+ return (uint8_t*)this + sizeof(_FX_FIXEDSTORECHUNK);
+ }
+ uint8_t* FirstBlock() const { return FirstFlag() + iChunkSize; }
+ _FX_FIXEDSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeNum;
+} FX_FIXEDSTORECHUNK, *FX_LPFIXEDSTORECHUNK;
+typedef FX_FIXEDSTORECHUNK const* FX_LPCFIXEDSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_FixedStore : public IFX_MEMAllocator, public CFX_Target {
+ public:
+ CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk);
+ virtual ~CFX_FixedStore();
+ virtual void Release() { delete this; }
+ virtual void* Alloc(size_t size);
+ virtual void Free(void* pBlock);
+ virtual size_t GetBlockSize() const { return m_iBlockSize; }
+ virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
+ virtual size_t SetDefChunkSize(size_t iChunkSize);
+ virtual size_t GetCurrentDataSize() const { return 0; }
+
+ protected:
+ size_t m_iBlockSize;
+ size_t m_iDefChunkSize;
+ FX_LPFIXEDSTORECHUNK m_pChunk;
+ FX_LPFIXEDSTORECHUNK AllocChunk();
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_DYNAMICSTOREBLOCK {
+ _FX_DYNAMICSTOREBLOCK* NextBlock() const {
+ return (_FX_DYNAMICSTOREBLOCK*)(Data() + iBlockSize);
+ }
+ uint8_t* Data() const {
+ return (uint8_t*)this + sizeof(_FX_DYNAMICSTOREBLOCK);
+ }
+ size_t iBlockSize;
+ FX_BOOL bUsed;
+} FX_DYNAMICSTOREBLOCK, *FX_LPDYNAMICSTOREBLOCK;
+typedef FX_DYNAMICSTOREBLOCK const* FX_LPCDYNAMICSTOREBLOCK;
+typedef struct _FX_DYNAMICSTORECHUNK {
+ FX_LPDYNAMICSTOREBLOCK FirstBlock() const {
+ return (FX_LPDYNAMICSTOREBLOCK)((uint8_t*)this +
+ sizeof(_FX_DYNAMICSTORECHUNK));
+ }
+ _FX_DYNAMICSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeSize;
+} FX_DYNAMICSTORECHUNK, *FX_LPDYNAMICSTORECHUNK;
+typedef FX_DYNAMICSTORECHUNK const* FX_LPCDYNAMICSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_DynamicStore : public IFX_MEMAllocator, public CFX_Target {
+ public:
+ CFX_DynamicStore(size_t iDefChunkSize = 4096);
+ virtual ~CFX_DynamicStore();
+ virtual void Release() { delete this; }
+ virtual void* Alloc(size_t size);
+ virtual void Free(void* pBlock);
+ virtual size_t GetBlockSize() const { return 0; }
+ virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; }
+ virtual size_t SetDefChunkSize(size_t size);
+ virtual size_t GetCurrentDataSize() const { return 0; }
+
+ protected:
+ size_t m_iDefChunkSize;
+ FX_LPDYNAMICSTORECHUNK m_pChunk;
+ FX_LPDYNAMICSTORECHUNK AllocChunk(size_t size);
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_stream.cpp b/xfa/src/fgas/src/crt/fx_stream.cpp
index d862167f57..243a5c3c43 100644
--- a/xfa/src/fgas/src/crt/fx_stream.cpp
+++ b/xfa/src/fgas/src/crt/fx_stream.cpp
@@ -1,1357 +1,1357 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_stream.h"
-IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead* pBufferRead,
- FX_DWORD dwAccess,
- int32_t iFileSize,
- FX_BOOL bReleaseBufferRead) {
- CFX_Stream* pSR = new CFX_Stream;
- if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess,
- bReleaseBufferRead)) {
- pSR->Release();
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-IFX_Stream* IFX_Stream::CreateStream(IFX_FileRead* pFileRead,
- FX_DWORD dwAccess) {
- CFX_Stream* pSR = new CFX_Stream;
- if (!pSR->LoadFileRead(pFileRead, dwAccess)) {
- pSR->Release();
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-IFX_Stream* IFX_Stream::CreateStream(IFX_FileWrite* pFileWrite,
- FX_DWORD dwAccess) {
- CFX_Stream* pSR = new CFX_Stream;
- if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) {
- pSR->Release();
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-IFX_Stream* IFX_Stream::CreateStream(const FX_WCHAR* pszFileName,
- FX_DWORD dwAccess) {
- CFX_Stream* pSR = new CFX_Stream;
- if (!pSR->LoadFile(pszFileName, dwAccess)) {
- pSR->Release();
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-IFX_Stream* IFX_Stream::CreateStream(uint8_t* pData,
- int32_t length,
- FX_DWORD dwAccess) {
- CFX_Stream* pSR = new CFX_Stream;
- if (!pSR->LoadBuffer(pData, length, dwAccess)) {
- pSR->Release();
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-CFX_StreamImp::CFX_StreamImp() : CFX_ThreadLock(), m_dwAccess(0) {}
-CFX_FileStreamImp::CFX_FileStreamImp()
- : CFX_StreamImp(), m_hFile(NULL), m_iLength(0) {}
-CFX_FileStreamImp::~CFX_FileStreamImp() {
- if (m_hFile != NULL) {
- FXSYS_fclose(m_hFile);
- }
-}
-FX_BOOL CFX_FileStreamImp::LoadFile(const FX_WCHAR* pszSrcFileName,
- FX_DWORD dwAccess) {
- FXSYS_assert(m_hFile == NULL);
- FXSYS_assert(pszSrcFileName != NULL && FXSYS_wcslen(pszSrcFileName) > 0);
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
- CFX_WideString wsMode;
- if (dwAccess & FX_STREAMACCESS_Write) {
- if (dwAccess & FX_STREAMACCESS_Append) {
- wsMode = L"a+b";
- } else if (dwAccess & FX_STREAMACCESS_Truncate) {
- wsMode = L"w+b";
- } else {
- wsMode = L"r+b";
- }
- } else {
- wsMode = L"rb";
- }
-#ifdef _FX_WINAPI_PARTITION_APP_
- CFX_WideString wsSrcFileName(pszSrcFileName);
- _wfopen_s(&m_hFile, wsSrcFileName, wsMode);
-#else
- m_hFile = FXSYS_wfopen(pszSrcFileName, wsMode);
-#endif
- if (m_hFile == NULL) {
- if (dwAccess & FX_STREAMACCESS_Write) {
- if (dwAccess & FX_STREAMACCESS_Create) {
-#ifdef _FX_WINAPI_PARTITION_APP_
- CFX_WideString wsSrcFileName(pszSrcFileName);
- _wfopen_s(&m_hFile, wsSrcFileName, L"w+b");
-#else
- m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b");
-#endif
- }
- if (m_hFile == NULL) {
-#ifdef _FX_WINAPI_PARTITION_APP_
- CFX_WideString wsSrcFileName(pszSrcFileName);
- _wfopen_s(&m_hFile, wsSrcFileName, L"r+b");
-#else
- m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b");
-#endif
- if (m_hFile == NULL) {
- return FALSE;
- }
- if (dwAccess & FX_STREAMACCESS_Truncate) {
- FX_fsetsize(m_hFile, 0);
- }
- }
- } else {
- return FALSE;
- }
- }
-#else
- CFX_ByteString wsMode;
- if (dwAccess & FX_STREAMACCESS_Write) {
- if (dwAccess & FX_STREAMACCESS_Append) {
- wsMode = "a+b";
- } else if (dwAccess & FX_STREAMACCESS_Truncate) {
- wsMode = "w+b";
- } else {
- wsMode = "r+b";
- }
- } else {
- wsMode = "rb";
- }
- CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName);
- m_hFile = FXSYS_fopen(szFileName, wsMode);
- if (m_hFile == NULL) {
- if (dwAccess & FX_STREAMACCESS_Write) {
- if (dwAccess & FX_STREAMACCESS_Create) {
- m_hFile = FXSYS_fopen(szFileName, "w+b");
- }
- if (m_hFile == NULL) {
- m_hFile = FXSYS_fopen(szFileName, "r+b");
- if (m_hFile == NULL) {
- return FALSE;
- }
- if (dwAccess & FX_STREAMACCESS_Truncate) {
- FX_fsetsize(m_hFile, 0);
- }
- }
- } else {
- return FALSE;
- }
- }
-#endif
- m_dwAccess = dwAccess;
- if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) ==
- (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) {
- m_iLength = 0;
- } else {
- m_iLength = FX_filelength(m_hFile);
- }
- return TRUE;
-}
-int32_t CFX_FileStreamImp::GetLength() const {
- FXSYS_assert(m_hFile != NULL);
- return m_iLength;
-}
-int32_t CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- FXSYS_assert(m_hFile != NULL);
- FXSYS_fseek(m_hFile, iOffset, eSeek);
- return FXSYS_ftell(m_hFile);
-}
-int32_t CFX_FileStreamImp::GetPosition() {
- FXSYS_assert(m_hFile != NULL);
- return FXSYS_ftell(m_hFile);
-}
-FX_BOOL CFX_FileStreamImp::IsEOF() const {
- FXSYS_assert(m_hFile != NULL);
- return FXSYS_ftell(m_hFile) >= m_iLength;
-}
-int32_t CFX_FileStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
- FXSYS_assert(m_hFile != NULL);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- return FXSYS_fread(pBuffer, 1, iBufferSize, m_hFile);
-}
-int32_t CFX_FileStreamImp::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) {
- FXSYS_assert(m_hFile != NULL);
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- if (m_iLength <= 0) {
- return 0;
- }
- int32_t iPosition = FXSYS_ftell(m_hFile);
- int32_t iLen = std::min((m_iLength - iPosition) / 2, iMaxLength);
- if (iLen <= 0) {
- return 0;
- }
- iLen = FXSYS_fread(pStr, 2, iLen, m_hFile);
- int32_t iCount = 0;
- while (*pStr != L'\0' && iCount < iLen) {
- pStr++, iCount++;
- }
- iPosition += iCount * 2;
- if (FXSYS_ftell(m_hFile) != iPosition) {
- FXSYS_fseek(m_hFile, iPosition, 0);
- }
- bEOS = (iPosition >= m_iLength);
- return iCount;
-}
-int32_t CFX_FileStreamImp::WriteData(const uint8_t* pBuffer,
- int32_t iBufferSize) {
- FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- int32_t iRet = FXSYS_fwrite(pBuffer, 1, iBufferSize, m_hFile);
- if (iRet != 0) {
- int32_t iPos = FXSYS_ftell(m_hFile);
- if (iPos > m_iLength) {
- m_iLength = iPos;
- }
- }
- return iRet;
-}
-int32_t CFX_FileStreamImp::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
- FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FXSYS_assert(pStr != NULL && iLength > 0);
- int32_t iRet = FXSYS_fwrite(pStr, 2, iLength, m_hFile);
- if (iRet != 0) {
- int32_t iPos = FXSYS_ftell(m_hFile);
- if (iPos > m_iLength) {
- m_iLength = iPos;
- }
- }
- return iRet;
-}
-void CFX_FileStreamImp::Flush() {
- FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FXSYS_fflush(m_hFile);
-}
-FX_BOOL CFX_FileStreamImp::SetLength(int32_t iLength) {
- FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FX_BOOL bRet = FX_fsetsize(m_hFile, iLength);
- m_iLength = FX_filelength(m_hFile);
- return bRet;
-}
-CFX_FileReadStreamImp::CFX_FileReadStreamImp()
- : m_pFileRead(NULL), m_iPosition(0), m_iLength(0) {}
-FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead* pFileRead,
- FX_DWORD dwAccess) {
- FXSYS_assert(m_pFileRead == NULL && pFileRead != NULL);
- if (dwAccess & FX_STREAMACCESS_Write) {
- return FALSE;
- }
- m_pFileRead = pFileRead;
- m_iLength = m_pFileRead->GetSize();
- return TRUE;
-}
-int32_t CFX_FileReadStreamImp::GetLength() const {
- return m_iLength;
-}
-int32_t CFX_FileReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- switch (eSeek) {
- case FX_STREAMSEEK_Begin:
- m_iPosition = iOffset;
- break;
- case FX_STREAMSEEK_Current:
- m_iPosition += iOffset;
- break;
- case FX_STREAMSEEK_End:
- m_iPosition = m_iLength + iOffset;
- break;
- }
- if (m_iPosition < 0) {
- m_iPosition = 0;
- } else if (m_iPosition >= m_iLength) {
- m_iPosition = m_iLength;
- }
- return m_iPosition;
-}
-FX_BOOL CFX_FileReadStreamImp::IsEOF() const {
- return m_iPosition >= m_iLength;
-}
-int32_t CFX_FileReadStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
- FXSYS_assert(m_pFileRead != NULL);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- if (iBufferSize > m_iLength - m_iPosition) {
- iBufferSize = m_iLength - m_iPosition;
- }
- if (m_pFileRead->ReadBlock(pBuffer, m_iPosition, iBufferSize)) {
- m_iPosition += iBufferSize;
- return iBufferSize;
- }
- return 0;
-}
-int32_t CFX_FileReadStreamImp::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) {
- FXSYS_assert(m_pFileRead != NULL);
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2;
- if (iMaxLength <= 0) {
- return 0;
- }
- int32_t i = 0;
- while (i < iMaxLength && pStr[i] != L'\0') {
- ++i;
- }
- bEOS = (m_iPosition >= m_iLength) || pStr[i] == L'\0';
- return i;
-}
-CFX_BufferReadStreamImp::CFX_BufferReadStreamImp()
- : m_pBufferRead(NULL),
- m_bReleaseBufferRead(FALSE),
- m_iPosition(0),
- m_iBufferSize(0) {}
-CFX_BufferReadStreamImp::~CFX_BufferReadStreamImp() {
- if (m_bReleaseBufferRead && m_pBufferRead != NULL) {
- m_pBufferRead->Release();
- }
-}
-FX_BOOL CFX_BufferReadStreamImp::LoadBufferRead(IFX_BufferRead* pBufferRead,
- int32_t iFileSize,
- FX_DWORD dwAccess,
- FX_BOOL bReleaseBufferRead) {
- FXSYS_assert(m_pBufferRead == NULL && pBufferRead != NULL);
- if (dwAccess & FX_STREAMACCESS_Write) {
- return FALSE;
- }
- m_bReleaseBufferRead = bReleaseBufferRead;
- m_pBufferRead = pBufferRead;
- m_iBufferSize = iFileSize;
- if (m_iBufferSize >= 0) {
- return TRUE;
- }
- if (!m_pBufferRead->ReadNextBlock(TRUE)) {
- return FALSE;
- }
- m_iBufferSize = m_pBufferRead->GetBlockSize();
- while (!m_pBufferRead->IsEOF()) {
- m_pBufferRead->ReadNextBlock(FALSE);
- m_iBufferSize += m_pBufferRead->GetBlockSize();
- }
- return TRUE;
-}
-int32_t CFX_BufferReadStreamImp::GetLength() const {
- return m_iBufferSize;
-}
-int32_t CFX_BufferReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- int32_t iLength = GetLength();
- switch (eSeek) {
- case FX_STREAMSEEK_Begin:
- m_iPosition = iOffset;
- break;
- case FX_STREAMSEEK_Current:
- m_iPosition += iOffset;
- break;
- case FX_STREAMSEEK_End:
- m_iPosition = iLength + iOffset;
- break;
- }
- if (m_iPosition < 0) {
- m_iPosition = 0;
- } else if (m_iPosition >= iLength) {
- m_iPosition = iLength;
- }
- return m_iPosition;
-}
-FX_BOOL CFX_BufferReadStreamImp::IsEOF() const {
- return m_pBufferRead ? m_pBufferRead->IsEOF() : TRUE;
-}
-int32_t CFX_BufferReadStreamImp::ReadData(uint8_t* pBuffer,
- int32_t iBufferSize) {
- FXSYS_assert(m_pBufferRead != NULL);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- int32_t iLength = GetLength();
- if (m_iPosition >= iLength) {
- return 0;
- }
- if (iBufferSize > iLength - m_iPosition) {
- iBufferSize = iLength - m_iPosition;
- }
- FX_DWORD dwBlockOffset = m_pBufferRead->GetBlockOffset();
- FX_DWORD dwBlockSize = m_pBufferRead->GetBlockSize();
- if (m_iPosition < (int32_t)dwBlockOffset) {
- if (!m_pBufferRead->ReadNextBlock(TRUE)) {
- return 0;
- }
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- dwBlockSize = m_pBufferRead->GetBlockSize();
- }
- while (m_iPosition < (int32_t)dwBlockOffset ||
- m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) {
- if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
- break;
- }
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- dwBlockSize = m_pBufferRead->GetBlockSize();
- }
- if (m_iPosition < (int32_t)dwBlockOffset ||
- m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) {
- return 0;
- }
- const uint8_t* pBufferTmp = m_pBufferRead->GetBlockBuffer();
- FX_DWORD dwOffsetTmp = m_iPosition - dwBlockOffset;
- FX_DWORD dwCopySize =
- std::min(iBufferSize, (int32_t)(dwBlockSize - dwOffsetTmp));
- FXSYS_memcpy(pBuffer, pBufferTmp + dwOffsetTmp, dwCopySize);
- dwOffsetTmp = dwCopySize;
- iBufferSize -= dwCopySize;
- while (iBufferSize > 0) {
- if (!m_pBufferRead->ReadNextBlock(FALSE)) {
- break;
- }
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- dwBlockSize = m_pBufferRead->GetBlockSize();
- pBufferTmp = m_pBufferRead->GetBlockBuffer();
- dwCopySize = std::min((FX_DWORD)iBufferSize, dwBlockSize);
- FXSYS_memcpy(pBuffer + dwOffsetTmp, pBufferTmp, dwCopySize);
- dwOffsetTmp += dwCopySize;
- iBufferSize -= dwCopySize;
- }
- m_iPosition += dwOffsetTmp;
- return dwOffsetTmp;
-}
-int32_t CFX_BufferReadStreamImp::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) {
- FXSYS_assert(m_pBufferRead != NULL);
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2;
- if (iMaxLength <= 0) {
- return 0;
- }
- int32_t i = 0;
- while (i < iMaxLength && pStr[i] != L'\0') {
- ++i;
- }
- bEOS = (m_iPosition >= GetLength()) || pStr[i] == L'\0';
- return i;
-}
-CFX_FileWriteStreamImp::CFX_FileWriteStreamImp()
- : m_pFileWrite(NULL), m_iPosition(0) {}
-FX_BOOL CFX_FileWriteStreamImp::LoadFileWrite(IFX_FileWrite* pFileWrite,
- FX_DWORD dwAccess) {
- FXSYS_assert(m_pFileWrite == NULL && pFileWrite != NULL);
- if (dwAccess & FX_STREAMACCESS_Read) {
- return FALSE;
- }
- if (dwAccess & FX_STREAMACCESS_Append) {
- m_iPosition = pFileWrite->GetSize();
- }
- m_pFileWrite = pFileWrite;
- return TRUE;
-}
-int32_t CFX_FileWriteStreamImp::GetLength() const {
- if (!m_pFileWrite) {
- return 0;
- }
- return (int32_t)m_pFileWrite->GetSize();
-}
-int32_t CFX_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- int32_t iLength = GetLength();
- switch (eSeek) {
- case FX_STREAMSEEK_Begin:
- m_iPosition = iOffset;
- break;
- case FX_STREAMSEEK_Current:
- m_iPosition += iOffset;
- break;
- case FX_STREAMSEEK_End:
- m_iPosition = iLength + iOffset;
- break;
- }
- if (m_iPosition < 0) {
- m_iPosition = 0;
- } else if (m_iPosition >= iLength) {
- m_iPosition = iLength;
- }
- return m_iPosition;
-}
-FX_BOOL CFX_FileWriteStreamImp::IsEOF() const {
- return m_iPosition >= GetLength();
-}
-int32_t CFX_FileWriteStreamImp::WriteData(const uint8_t* pBuffer,
- int32_t iBufferSize) {
- if (!m_pFileWrite) {
- return 0;
- }
- if (m_pFileWrite->WriteBlock(pBuffer, m_iPosition, iBufferSize)) {
- m_iPosition += iBufferSize;
- }
- return iBufferSize;
-}
-int32_t CFX_FileWriteStreamImp::WriteString(const FX_WCHAR* pStr,
- int32_t iLength) {
- return WriteData((const uint8_t*)pStr, iLength * sizeof(FX_WCHAR));
-}
-void CFX_FileWriteStreamImp::Flush() {
- if (m_pFileWrite) {
- m_pFileWrite->Flush();
- }
-}
-CFX_BufferStreamImp::CFX_BufferStreamImp()
- : CFX_StreamImp(),
- m_pData(NULL),
- m_iTotalSize(0),
- m_iPosition(0),
- m_iLength(0) {}
-FX_BOOL CFX_BufferStreamImp::LoadBuffer(uint8_t* pData,
- int32_t iTotalSize,
- FX_DWORD dwAccess) {
- FXSYS_assert(m_pData == NULL);
- FXSYS_assert(pData != NULL && iTotalSize > 0);
- m_dwAccess = dwAccess;
- m_pData = pData;
- m_iTotalSize = iTotalSize;
- m_iPosition = 0;
- m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iTotalSize;
- return TRUE;
-}
-int32_t CFX_BufferStreamImp::GetLength() const {
- FXSYS_assert(m_pData != NULL);
- return m_iLength;
-}
-int32_t CFX_BufferStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- FXSYS_assert(m_pData != NULL);
- if (eSeek == FX_STREAMSEEK_Begin) {
- m_iPosition = iOffset;
- } else if (eSeek == FX_STREAMSEEK_Current) {
- m_iPosition += iOffset;
- } else if (eSeek == FX_STREAMSEEK_End) {
- m_iPosition = m_iLength + iOffset;
- }
- if (m_iPosition > m_iLength) {
- m_iPosition = m_iLength;
- }
- if (m_iPosition < 0) {
- m_iPosition = 0;
- }
- return m_iPosition;
-}
-int32_t CFX_BufferStreamImp::GetPosition() {
- FXSYS_assert(m_pData != NULL);
- return m_iPosition;
-}
-FX_BOOL CFX_BufferStreamImp::IsEOF() const {
- FXSYS_assert(m_pData != NULL);
- return m_iPosition >= m_iLength;
-}
-int32_t CFX_BufferStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
- FXSYS_assert(m_pData != NULL);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- int32_t iLen = std::min(m_iLength - m_iPosition, iBufferSize);
- if (iLen <= 0) {
- return 0;
- }
- FXSYS_memcpy(pBuffer, m_pData + m_iPosition, iLen);
- m_iPosition += iLen;
- return iLen;
-}
-int32_t CFX_BufferStreamImp::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) {
- FXSYS_assert(m_pData != NULL);
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- int32_t iLen = std::min((m_iLength - m_iPosition) / 2, iMaxLength);
- if (iLen <= 0) {
- return 0;
- }
- const FX_WCHAR* pSrc = (const FX_WCHAR*)(FX_CHAR*)(m_pData + m_iPosition);
- int32_t iCount = 0;
- while (*pSrc != L'\0' && iCount < iLen) {
- *pStr++ = *pSrc++, iCount++;
- }
- m_iPosition += iCount * 2;
- bEOS = (*pSrc == L'\0') || (m_iPosition >= m_iLength);
- return iCount;
-}
-int32_t CFX_BufferStreamImp::WriteData(const uint8_t* pBuffer,
- int32_t iBufferSize) {
- FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- int32_t iLen = std::min(m_iTotalSize - m_iPosition, iBufferSize);
- if (iLen <= 0) {
- return 0;
- }
- FXSYS_memcpy(m_pData + m_iPosition, pBuffer, iLen);
- m_iPosition += iLen;
- if (m_iPosition > m_iLength) {
- m_iLength = m_iPosition;
- }
- return iLen;
-}
-int32_t CFX_BufferStreamImp::WriteString(const FX_WCHAR* pStr,
- int32_t iLength) {
- FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
- FXSYS_assert(pStr != NULL && iLength > 0);
- int32_t iLen = std::min((m_iTotalSize - m_iPosition) / 2, iLength);
- if (iLen <= 0) {
- return 0;
- }
- FXSYS_memcpy(m_pData + m_iPosition, pStr, iLen * 2);
- m_iPosition += iLen * 2;
- if (m_iPosition > m_iLength) {
- m_iLength = m_iPosition;
- }
- return iLen;
-}
-IFX_Stream* IFX_Stream::CreateTextStream(IFX_Stream* pBaseStream,
- FX_BOOL bDeleteOnRelease) {
- FXSYS_assert(pBaseStream != NULL);
- return new CFX_TextStream(pBaseStream, bDeleteOnRelease);
-}
-CFX_TextStream::CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream)
- : m_wCodePage(FX_CODEPAGE_DefANSI),
- m_wBOMLength(0),
- m_dwBOM(0),
- m_pBuf(NULL),
- m_iBufSize(0),
- m_bDelStream(bDelStream),
- m_pStreamImp(pStream),
- m_iRefCount(1) {
- FXSYS_assert(m_pStreamImp != NULL);
- m_pStreamImp->Retain();
- InitStream();
-}
-CFX_TextStream::~CFX_TextStream() {
- m_pStreamImp->Release();
- if (m_bDelStream) {
- m_pStreamImp->Release();
- }
- if (m_pBuf != NULL) {
- FX_Free(m_pBuf);
- }
-}
-void CFX_TextStream::InitStream() {
- int32_t iPosition = m_pStreamImp->GetPosition();
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, 0);
- m_pStreamImp->ReadData((uint8_t*)&m_dwBOM, 3);
-#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
- m_dwBOM &= 0x00FFFFFF;
- if (m_dwBOM == 0x00BFBBEF) {
- m_wBOMLength = 3;
- m_wCodePage = FX_CODEPAGE_UTF8;
- } else {
- m_dwBOM &= 0x0000FFFF;
- if (m_dwBOM == 0x0000FFFE) {
- m_wBOMLength = 2;
- m_wCodePage = FX_CODEPAGE_UTF16BE;
- } else if (m_dwBOM == 0x0000FEFF) {
- m_wBOMLength = 2;
- m_wCodePage = FX_CODEPAGE_UTF16LE;
- } else {
- m_wBOMLength = 0;
- m_dwBOM = 0;
- m_wCodePage = FXSYS_GetACP();
- }
- }
-#else
- m_dwBOM &= 0xFFFFFF00;
- if (m_dwBOM == 0xEFBBBF00) {
- m_wBOMLength = 3;
- m_wCodePage = FX_CODEPAGE_UTF8;
- } else {
- m_dwBOM &= 0xFFFF0000;
- if (m_dwBOM == 0xFEFF0000) {
- m_wBOMLength = 2;
- m_wCodePage = FX_CODEPAGE_UTF16BE;
- } else if (m_dwBOM == 0xFFFE0000) {
- m_wBOMLength = 2;
- m_wCodePage = FX_CODEPAGE_UTF16LE;
- } else {
- m_wBOMLength = 0;
- m_dwBOM = 0;
- m_wCodePage = FXSYS_GetACP();
- }
- }
-#endif
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, std::max(m_wBOMLength, iPosition));
-}
-void CFX_TextStream::Release() {
- if (--m_iRefCount < 1) {
- delete this;
- }
-}
-IFX_Stream* CFX_TextStream::Retain() {
- m_iRefCount++;
- return this;
-}
-FX_DWORD CFX_TextStream::GetAccessModes() const {
- return m_pStreamImp->GetAccessModes() | FX_STREAMACCESS_Text;
-}
-int32_t CFX_TextStream::GetLength() const {
- return m_pStreamImp->GetLength();
-}
-int32_t CFX_TextStream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- return m_pStreamImp->Seek(eSeek, iOffset);
-}
-int32_t CFX_TextStream::GetPosition() {
- return m_pStreamImp->GetPosition();
-}
-FX_BOOL CFX_TextStream::IsEOF() const {
- return m_pStreamImp->IsEOF();
-}
-int32_t CFX_TextStream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
- return m_pStreamImp->ReadData(pBuffer, iBufferSize);
-}
-int32_t CFX_TextStream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
- return m_pStreamImp->WriteData(pBuffer, iBufferSize);
-}
-void CFX_TextStream::Flush() {
- m_pStreamImp->Flush();
-}
-FX_BOOL CFX_TextStream::SetLength(int32_t iLength) {
- return m_pStreamImp->SetLength(iLength);
-}
-FX_WORD CFX_TextStream::GetCodePage() const {
- return m_wCodePage;
-}
-IFX_Stream* CFX_TextStream::CreateSharedStream(FX_DWORD dwAccess,
- int32_t iOffset,
- int32_t iLength) {
- IFX_Stream* pSR =
- m_pStreamImp->CreateSharedStream(dwAccess, iOffset, iLength);
- if (pSR == NULL) {
- return NULL;
- }
- if (dwAccess & FX_STREAMACCESS_Text) {
- return new CFX_TextStream(pSR, TRUE);
- }
- return pSR;
-}
-int32_t CFX_TextStream::GetBOM(uint8_t bom[4]) const {
- if (m_wBOMLength < 1) {
- return 0;
- }
- *(FX_DWORD*)bom = m_dwBOM;
- return m_wBOMLength;
-}
-FX_WORD CFX_TextStream::SetCodePage(FX_WORD wCodePage) {
- if (m_wBOMLength > 0) {
- return m_wCodePage;
- }
- FX_WORD v = m_wCodePage;
- m_wCodePage = wCodePage;
- return v;
-}
-int32_t CFX_TextStream::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS,
- int32_t const* pByteSize) {
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- if (m_pStreamImp == NULL) {
- return -1;
- }
- int32_t iLen;
- if (m_wCodePage == FX_CODEPAGE_UTF16LE ||
- m_wCodePage == FX_CODEPAGE_UTF16BE) {
- int32_t iBytes = pByteSize == NULL ? iMaxLength * 2 : *pByteSize;
- m_pStreamImp->Lock();
- iLen = m_pStreamImp->ReadData((uint8_t*)pStr, iBytes);
- m_pStreamImp->Unlock();
- iMaxLength = iLen / 2;
- if (sizeof(FX_WCHAR) > 2) {
- FX_UTF16ToWChar(pStr, iMaxLength);
- }
-#if _FX_ENDIAN_ == _FX_BIG_ENDIAN_
- if (m_wCodePage == FX_CODEPAGE_UTF16LE) {
- FX_SwapByteOrder(pStr, iMaxLength);
- }
-#else
- if (m_wCodePage == FX_CODEPAGE_UTF16BE) {
- FX_SwapByteOrder(pStr, iMaxLength);
- }
-#endif
- } else {
- int32_t pos = m_pStreamImp->GetPosition();
- int32_t iBytes = pByteSize == NULL ? iMaxLength : *pByteSize;
- iBytes = std::min(iBytes, m_pStreamImp->GetLength() - pos);
- if (iBytes > 0) {
- if (m_pBuf == NULL) {
- m_pBuf = FX_Alloc(uint8_t, iBytes);
- m_iBufSize = iBytes;
- } else if (iBytes > m_iBufSize) {
- m_pBuf = FX_Realloc(uint8_t, m_pBuf, iBytes);
- m_iBufSize = iBytes;
- }
- m_pStreamImp->Lock();
- iLen = m_pStreamImp->ReadData(m_pBuf, iBytes);
- int32_t iSrc = iLen;
- int32_t iDecode = FX_DecodeString(m_wCodePage, (const FX_CHAR*)m_pBuf,
- &iSrc, pStr, &iMaxLength, TRUE);
- m_pStreamImp->Seek(FX_STREAMSEEK_Current, iSrc - iLen);
- m_pStreamImp->Unlock();
- if (iDecode < 1) {
- return -1;
- }
- } else {
- iMaxLength = 0;
- }
- }
- bEOS = m_pStreamImp->IsEOF();
- return iMaxLength;
-}
-int32_t CFX_TextStream::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
- FXSYS_assert(pStr != NULL && iLength > 0);
- if ((m_pStreamImp->GetAccessModes() & FX_STREAMACCESS_Write) == 0) {
- return -1;
- }
- if (m_wCodePage == FX_CODEPAGE_UTF8) {
- int32_t len = iLength;
- CFX_UTF8Encoder encoder;
- while (len-- > 0) {
- encoder.Input(*pStr++);
- }
- CFX_ByteStringC bsResult = encoder.GetResult();
- m_pStreamImp->Lock();
- m_pStreamImp->WriteData((const uint8_t*)bsResult.GetCStr(),
- bsResult.GetLength());
- m_pStreamImp->Unlock();
- }
- return iLength;
-}
-CFX_Stream::CFX_Stream()
- : m_eStreamType(FX_SREAMTYPE_Unknown),
- m_pStreamImp(NULL),
- m_dwAccess(0),
- m_iTotalSize(0),
- m_iPosition(0),
- m_iStart(0),
- m_iLength(0),
- m_iRefCount(1) {}
-CFX_Stream::~CFX_Stream() {
- if (m_eStreamType != FX_STREAMTYPE_Stream && m_pStreamImp != NULL) {
- m_pStreamImp->Release();
- }
-}
-FX_BOOL CFX_Stream::LoadFile(const FX_WCHAR* pszSrcFileName,
- FX_DWORD dwAccess) {
- if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
- return FALSE;
- }
- if (pszSrcFileName == NULL || FXSYS_wcslen(pszSrcFileName) < 1) {
- return FALSE;
- }
- m_pStreamImp = new CFX_FileStreamImp();
- FX_BOOL bRet =
- ((CFX_FileStreamImp*)m_pStreamImp)->LoadFile(pszSrcFileName, dwAccess);
- if (!bRet) {
- m_pStreamImp->Release();
- m_pStreamImp = NULL;
- } else {
- m_eStreamType = FX_STREAMTYPE_File;
- m_dwAccess = dwAccess;
- m_iLength = m_pStreamImp->GetLength();
- }
- return bRet;
-}
-FX_BOOL CFX_Stream::LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess) {
- if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
- return FALSE;
- }
- if (pFileRead == NULL) {
- return FALSE;
- }
- m_pStreamImp = new CFX_FileReadStreamImp();
- FX_BOOL bRet =
- ((CFX_FileReadStreamImp*)m_pStreamImp)->LoadFileRead(pFileRead, dwAccess);
- if (!bRet) {
- m_pStreamImp->Release();
- m_pStreamImp = NULL;
- } else {
- m_eStreamType = FX_STREAMTYPE_File;
- m_dwAccess = dwAccess;
- m_iLength = m_pStreamImp->GetLength();
- }
- return bRet;
-}
-FX_BOOL CFX_Stream::LoadFileWrite(IFX_FileWrite* pFileWrite,
- FX_DWORD dwAccess) {
- if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
- return FALSE;
- }
- if (pFileWrite == NULL) {
- return FALSE;
- }
- m_pStreamImp = new CFX_FileWriteStreamImp();
- FX_BOOL bRet = ((CFX_FileWriteStreamImp*)m_pStreamImp)
- ->LoadFileWrite(pFileWrite, dwAccess);
- if (!bRet) {
- m_pStreamImp->Release();
- m_pStreamImp = NULL;
- } else {
- m_eStreamType = FX_STREAMTYPE_File;
- m_dwAccess = dwAccess;
- m_iLength = m_pStreamImp->GetLength();
- }
- return bRet;
-}
-FX_BOOL CFX_Stream::LoadBuffer(uint8_t* pData,
- int32_t iTotalSize,
- FX_DWORD dwAccess) {
- if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
- return FALSE;
- }
- if (pData == NULL || iTotalSize < 1) {
- return FALSE;
- }
- m_pStreamImp = new CFX_BufferStreamImp();
- FX_BOOL bRet = ((CFX_BufferStreamImp*)m_pStreamImp)
- ->LoadBuffer(pData, iTotalSize, dwAccess);
- if (!bRet) {
- m_pStreamImp->Release();
- m_pStreamImp = NULL;
- } else {
- m_eStreamType = FX_STREAMTYPE_Buffer;
- m_dwAccess = dwAccess;
- m_iLength = m_pStreamImp->GetLength();
- }
- return bRet;
-}
-FX_BOOL CFX_Stream::LoadBufferRead(IFX_BufferRead* pBufferRead,
- int32_t iFileSize,
- FX_DWORD dwAccess,
- FX_BOOL bReleaseBufferRead) {
- if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
- return FALSE;
- }
- if (!pBufferRead) {
- return FALSE;
- }
- m_pStreamImp = new CFX_BufferReadStreamImp;
- FX_BOOL bRet = ((CFX_BufferReadStreamImp*)m_pStreamImp)
- ->LoadBufferRead(pBufferRead, iFileSize, dwAccess,
- bReleaseBufferRead);
- if (!bRet) {
- m_pStreamImp->Release();
- m_pStreamImp = NULL;
- } else {
- m_eStreamType = FX_STREAMTYPE_BufferRead;
- m_dwAccess = dwAccess;
- m_iLength = m_pStreamImp->GetLength();
- }
- return bRet;
-}
-void CFX_Stream::Release() {
- if (--m_iRefCount < 1) {
- delete this;
- }
-}
-IFX_Stream* CFX_Stream::Retain() {
- m_iRefCount++;
- return this;
-}
-int32_t CFX_Stream::GetLength() const {
- if (m_pStreamImp == NULL) {
- return -1;
- }
- if (m_eStreamType == FX_STREAMTYPE_File ||
- m_eStreamType == FX_STREAMTYPE_Buffer) {
- return m_pStreamImp->GetLength();
- }
- return m_iLength;
-}
-int32_t CFX_Stream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
- if (m_pStreamImp == NULL) {
- return -1;
- }
- if (m_eStreamType == FX_STREAMTYPE_File ||
- m_eStreamType == FX_STREAMTYPE_Buffer) {
- return m_iPosition = m_pStreamImp->Seek(eSeek, iOffset);
- }
- int32_t iEnd = m_iStart + m_iLength;
- int32_t iPosition = m_iStart + iOffset;
- if (eSeek == FX_STREAMSEEK_Begin) {
- m_iPosition = iPosition;
- } else if (eSeek == FX_STREAMSEEK_Current) {
- m_iPosition += iOffset;
- } else if (eSeek == FX_STREAMSEEK_End) {
- m_iPosition = iEnd + iOffset;
- }
- if (m_iPosition > iEnd) {
- m_iPosition = iEnd;
- }
- if (m_iPosition < m_iStart) {
- m_iPosition = m_iStart;
- }
- return m_iPosition - m_iStart;
-}
-int32_t CFX_Stream::GetPosition() {
- if (m_pStreamImp == NULL) {
- return -1;
- }
- if (m_eStreamType == FX_STREAMTYPE_File ||
- m_eStreamType == FX_STREAMTYPE_Buffer) {
- return m_iPosition = m_pStreamImp->GetPosition();
- }
- return m_iPosition - m_iStart;
-}
-FX_BOOL CFX_Stream::IsEOF() const {
- if (m_pStreamImp == NULL) {
- return TRUE;
- }
- if (m_eStreamType == FX_STREAMTYPE_File ||
- m_eStreamType == FX_STREAMTYPE_Buffer) {
- return m_pStreamImp->IsEOF();
- }
- return m_iPosition >= m_iStart + m_iLength;
-}
-int32_t CFX_Stream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- if (m_pStreamImp == NULL) {
- return -1;
- }
- int32_t iLen = std::min(m_iStart + m_iLength - m_iPosition, iBufferSize);
- if (iLen <= 0) {
- return 0;
- }
- m_pStreamImp->Lock();
- if (m_pStreamImp->GetPosition() != m_iPosition) {
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
- }
- iLen = m_pStreamImp->ReadData(pBuffer, iLen);
- m_iPosition = m_pStreamImp->GetPosition();
- m_pStreamImp->Unlock();
- return iLen;
-}
-int32_t CFX_Stream::ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS,
- int32_t const* pByteSize) {
- FXSYS_assert(pStr != NULL && iMaxLength > 0);
- if (m_pStreamImp == NULL) {
- return -1;
- }
- int32_t iEnd = m_iStart + m_iLength;
- int32_t iLen = iEnd - m_iPosition;
- if (pByteSize != NULL) {
- iLen = std::min(iLen, *pByteSize);
- }
- iLen = std::min(iEnd / 2, iMaxLength);
- if (iLen <= 0) {
- return 0;
- }
- m_pStreamImp->Lock();
- if (m_pStreamImp->GetPosition() != m_iPosition) {
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
- }
- iLen = m_pStreamImp->ReadString(pStr, iLen, bEOS);
- m_iPosition = m_pStreamImp->GetPosition();
- if (iLen > 0 && m_iPosition >= iEnd) {
- bEOS = TRUE;
- }
- m_pStreamImp->Unlock();
- return iLen;
-}
-int32_t CFX_Stream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
- FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
- if (m_pStreamImp == NULL) {
- return -1;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
- return -1;
- }
- int32_t iLen = iBufferSize;
- if (m_eStreamType == FX_STREAMTYPE_Stream) {
- iLen = std::min(m_iStart + m_iTotalSize - m_iPosition, iBufferSize);
- if (iLen <= 0) {
- return 0;
- }
- }
- m_pStreamImp->Lock();
- int32_t iEnd = m_iStart + m_iLength;
- if (m_pStreamImp->GetPosition() != m_iPosition) {
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
- }
- iLen = m_pStreamImp->WriteData(pBuffer, iLen);
- m_iPosition = m_pStreamImp->GetPosition();
- if (m_iPosition > iEnd) {
- m_iLength = m_iPosition - m_iStart;
- }
- m_pStreamImp->Unlock();
- return iLen;
-}
-int32_t CFX_Stream::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
- FXSYS_assert(pStr != NULL && iLength > 0);
- if (m_pStreamImp == NULL) {
- return -1;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
- return -1;
- }
- int32_t iLen = iLength;
- if (m_eStreamType == FX_STREAMTYPE_Stream) {
- iLen = std::min((m_iStart + m_iTotalSize - m_iPosition) / 2, iLength);
- if (iLen <= 0) {
- return 0;
- }
- }
- m_pStreamImp->Lock();
- int32_t iEnd = m_iStart + m_iLength;
- if (m_pStreamImp->GetPosition() != m_iPosition) {
- m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
- }
- iLen = m_pStreamImp->WriteString(pStr, iLen);
- m_iPosition = m_pStreamImp->GetPosition();
- if (m_iPosition > iEnd) {
- m_iLength = m_iPosition - m_iStart;
- }
- m_pStreamImp->Unlock();
- return iLen;
-}
-void CFX_Stream::Flush() {
- if (m_pStreamImp == NULL) {
- return;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
- return;
- }
- m_pStreamImp->Flush();
-}
-FX_BOOL CFX_Stream::SetLength(int32_t iLength) {
- if (m_pStreamImp == NULL) {
- return FALSE;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
- return FALSE;
- }
- return m_pStreamImp->SetLength(iLength);
-}
-int32_t CFX_Stream::GetBOM(uint8_t bom[4]) const {
- if (m_pStreamImp == NULL) {
- return -1;
- }
- return 0;
-}
-FX_WORD CFX_Stream::GetCodePage() const {
-#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
- return FX_CODEPAGE_UTF16LE;
-#else
- return FX_CODEPAGE_UTF16BE;
-#endif
-}
-FX_WORD CFX_Stream::SetCodePage(FX_WORD wCodePage) {
-#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
- return FX_CODEPAGE_UTF16LE;
-#else
- return FX_CODEPAGE_UTF16BE;
-#endif
-}
-IFX_Stream* CFX_Stream::CreateSharedStream(FX_DWORD dwAccess,
- int32_t iOffset,
- int32_t iLength) {
- FXSYS_assert(iLength > 0);
- if (m_pStreamImp == NULL) {
- return NULL;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Text) != 0 &&
- (dwAccess & FX_STREAMACCESS_Text) == 0) {
- return NULL;
- }
- if ((m_dwAccess & FX_STREAMACCESS_Write) == 0 &&
- (dwAccess & FX_STREAMACCESS_Write) != 0) {
- return NULL;
- }
- int32_t iStart = m_iStart + iOffset;
- int32_t iTotal = m_iStart + m_iLength;
- if (iStart < m_iStart || iStart >= iTotal) {
- return NULL;
- }
- int32_t iEnd = iStart + iLength;
- if (iEnd < iStart || iEnd > iTotal) {
- return NULL;
- }
- CFX_Stream* pShared = new CFX_Stream;
- pShared->m_eStreamType = FX_STREAMTYPE_Stream;
- pShared->m_pStreamImp = m_pStreamImp;
- pShared->m_dwAccess = dwAccess;
- pShared->m_iTotalSize = iLength;
- pShared->m_iPosition = iStart;
- pShared->m_iStart = iStart;
- pShared->m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iLength;
- if (dwAccess & FX_STREAMACCESS_Text) {
- return IFX_Stream::CreateTextStream(pShared, TRUE);
- }
- return pShared;
-}
-IFX_FileRead* FX_CreateFileRead(IFX_Stream* pBaseStream,
- FX_BOOL bReleaseStream) {
- FXSYS_assert(pBaseStream != NULL);
- return new CFGAS_FileRead(pBaseStream, bReleaseStream);
-}
-CFGAS_FileRead::CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream)
- : m_bReleaseStream(bReleaseStream), m_pStream(pStream) {
- FXSYS_assert(m_pStream != NULL);
-}
-CFGAS_FileRead::~CFGAS_FileRead() {
- if (m_bReleaseStream) {
- m_pStream->Release();
- }
-}
-FX_FILESIZE CFGAS_FileRead::GetSize() {
- return (FX_FILESIZE)m_pStream->GetLength();
-}
-FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer,
- FX_FILESIZE offset,
- size_t size) {
- m_pStream->Lock();
- m_pStream->Seek(FX_STREAMSEEK_Begin, (int32_t)offset);
- int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size);
- m_pStream->Unlock();
- return iLen == (int32_t)size;
-}
-
-IFX_FileRead* FX_CreateFileRead(IFX_BufferRead* pBufferRead,
- FX_FILESIZE iFileSize,
- FX_BOOL bReleaseStream) {
- if (!pBufferRead) {
- return NULL;
- }
- return new CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream);
-}
-CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead* pBufferRead,
- FX_FILESIZE iFileSize,
- FX_BOOL bReleaseStream)
- : m_pBufferRead(pBufferRead),
- m_bReleaseStream(bReleaseStream),
- m_iBufSize(iFileSize) {
- FXSYS_assert(m_pBufferRead);
-}
-CFX_BufferAccImp::~CFX_BufferAccImp() {
- if (m_bReleaseStream && m_pBufferRead) {
- m_pBufferRead->Release();
- }
-}
-FX_FILESIZE CFX_BufferAccImp::GetSize() {
- if (!m_pBufferRead) {
- return 0;
- }
- if (m_iBufSize >= 0) {
- return m_iBufSize;
- }
- if (!m_pBufferRead->ReadNextBlock(TRUE)) {
- return 0;
- }
- m_iBufSize = (FX_FILESIZE)m_pBufferRead->GetBlockSize();
- while (!m_pBufferRead->IsEOF()) {
- m_pBufferRead->ReadNextBlock(FALSE);
- m_iBufSize += (FX_FILESIZE)m_pBufferRead->GetBlockSize();
- }
- return m_iBufSize;
-}
-FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer,
- FX_FILESIZE offset,
- size_t size) {
- if (!m_pBufferRead) {
- return FALSE;
- }
- if (!buffer || !size) {
- return TRUE;
- }
- FX_FILESIZE dwBufSize = GetSize();
- if (offset >= dwBufSize) {
- return FALSE;
- }
- size_t dwBlockSize = m_pBufferRead->GetBlockSize();
- FX_FILESIZE dwBlockOffset = m_pBufferRead->GetBlockOffset();
- if (offset < dwBlockOffset) {
- if (!m_pBufferRead->ReadNextBlock(TRUE)) {
- return FALSE;
- }
- dwBlockSize = m_pBufferRead->GetBlockSize();
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- }
- while (offset < dwBlockOffset ||
- offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
- if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
- break;
- }
- dwBlockSize = m_pBufferRead->GetBlockSize();
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- }
- if (offset < dwBlockOffset ||
- offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
- return FALSE;
- }
- const uint8_t* pBuffer = m_pBufferRead->GetBlockBuffer();
- const FX_FILESIZE dwOffset = offset - dwBlockOffset;
- size_t dwCopySize =
- std::min(size, static_cast<size_t>(dwBlockSize - dwOffset));
- FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize);
- offset = dwCopySize;
- size -= dwCopySize;
- while (size) {
- if (!m_pBufferRead->ReadNextBlock(FALSE)) {
- break;
- }
- dwBlockOffset = m_pBufferRead->GetBlockOffset();
- dwBlockSize = m_pBufferRead->GetBlockSize();
- pBuffer = m_pBufferRead->GetBlockBuffer();
- dwCopySize = std::min(size, dwBlockSize);
- FXSYS_memcpy(((uint8_t*)buffer) + offset, pBuffer, dwCopySize);
- offset += dwCopySize;
- size -= dwCopySize;
- }
- return TRUE;
-}
-
-IFX_FileWrite* FX_CreateFileWrite(IFX_Stream* pBaseStream,
- FX_BOOL bReleaseStream) {
- FXSYS_assert(pBaseStream != NULL);
- return new CFGAS_FileWrite(pBaseStream, bReleaseStream);
-}
-
-CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream)
- : m_pStream(pStream), m_bReleaseStream(bReleaseStream) {
- FXSYS_assert(m_pStream != NULL);
-}
-CFGAS_FileWrite::~CFGAS_FileWrite() {
- if (m_bReleaseStream) {
- m_pStream->Release();
- }
-}
-FX_FILESIZE CFGAS_FileWrite::GetSize() {
- return m_pStream->GetLength();
-}
-FX_BOOL CFGAS_FileWrite::Flush() {
- m_pStream->Flush();
- return TRUE;
-}
-FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, size_t size) {
- return m_pStream->WriteData((const uint8_t*)pData, (int32_t)size) ==
- (int32_t)size;
-}
-FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData,
- FX_FILESIZE offset,
- size_t size) {
- m_pStream->Lock();
- m_pStream->Seek(FX_STREAMSEEK_Begin, offset);
- int32_t iLen = m_pStream->WriteData((uint8_t*)pData, (int32_t)size);
- m_pStream->Unlock();
- return iLen == (int32_t)size;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_stream.h"
+IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead* pBufferRead,
+ FX_DWORD dwAccess,
+ int32_t iFileSize,
+ FX_BOOL bReleaseBufferRead) {
+ CFX_Stream* pSR = new CFX_Stream;
+ if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess,
+ bReleaseBufferRead)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(IFX_FileRead* pFileRead,
+ FX_DWORD dwAccess) {
+ CFX_Stream* pSR = new CFX_Stream;
+ if (!pSR->LoadFileRead(pFileRead, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(IFX_FileWrite* pFileWrite,
+ FX_DWORD dwAccess) {
+ CFX_Stream* pSR = new CFX_Stream;
+ if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(const FX_WCHAR* pszFileName,
+ FX_DWORD dwAccess) {
+ CFX_Stream* pSR = new CFX_Stream;
+ if (!pSR->LoadFile(pszFileName, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(uint8_t* pData,
+ int32_t length,
+ FX_DWORD dwAccess) {
+ CFX_Stream* pSR = new CFX_Stream;
+ if (!pSR->LoadBuffer(pData, length, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+CFX_StreamImp::CFX_StreamImp() : CFX_ThreadLock(), m_dwAccess(0) {}
+CFX_FileStreamImp::CFX_FileStreamImp()
+ : CFX_StreamImp(), m_hFile(NULL), m_iLength(0) {}
+CFX_FileStreamImp::~CFX_FileStreamImp() {
+ if (m_hFile != NULL) {
+ FXSYS_fclose(m_hFile);
+ }
+}
+FX_BOOL CFX_FileStreamImp::LoadFile(const FX_WCHAR* pszSrcFileName,
+ FX_DWORD dwAccess) {
+ FXSYS_assert(m_hFile == NULL);
+ FXSYS_assert(pszSrcFileName != NULL && FXSYS_wcslen(pszSrcFileName) > 0);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+ CFX_WideString wsMode;
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ wsMode = L"a+b";
+ } else if (dwAccess & FX_STREAMACCESS_Truncate) {
+ wsMode = L"w+b";
+ } else {
+ wsMode = L"r+b";
+ }
+ } else {
+ wsMode = L"rb";
+ }
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, wsMode);
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, wsMode);
+#endif
+ if (m_hFile == NULL) {
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Create) {
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, L"w+b");
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b");
+#endif
+ }
+ if (m_hFile == NULL) {
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, L"r+b");
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b");
+#endif
+ if (m_hFile == NULL) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Truncate) {
+ FX_fsetsize(m_hFile, 0);
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+#else
+ CFX_ByteString wsMode;
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ wsMode = "a+b";
+ } else if (dwAccess & FX_STREAMACCESS_Truncate) {
+ wsMode = "w+b";
+ } else {
+ wsMode = "r+b";
+ }
+ } else {
+ wsMode = "rb";
+ }
+ CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName);
+ m_hFile = FXSYS_fopen(szFileName, wsMode);
+ if (m_hFile == NULL) {
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Create) {
+ m_hFile = FXSYS_fopen(szFileName, "w+b");
+ }
+ if (m_hFile == NULL) {
+ m_hFile = FXSYS_fopen(szFileName, "r+b");
+ if (m_hFile == NULL) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Truncate) {
+ FX_fsetsize(m_hFile, 0);
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+#endif
+ m_dwAccess = dwAccess;
+ if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) ==
+ (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) {
+ m_iLength = 0;
+ } else {
+ m_iLength = FX_filelength(m_hFile);
+ }
+ return TRUE;
+}
+int32_t CFX_FileStreamImp::GetLength() const {
+ FXSYS_assert(m_hFile != NULL);
+ return m_iLength;
+}
+int32_t CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_fseek(m_hFile, iOffset, eSeek);
+ return FXSYS_ftell(m_hFile);
+}
+int32_t CFX_FileStreamImp::GetPosition() {
+ FXSYS_assert(m_hFile != NULL);
+ return FXSYS_ftell(m_hFile);
+}
+FX_BOOL CFX_FileStreamImp::IsEOF() const {
+ FXSYS_assert(m_hFile != NULL);
+ return FXSYS_ftell(m_hFile) >= m_iLength;
+}
+int32_t CFX_FileStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ return FXSYS_fread(pBuffer, 1, iBufferSize, m_hFile);
+}
+int32_t CFX_FileStreamImp::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) {
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_iLength <= 0) {
+ return 0;
+ }
+ int32_t iPosition = FXSYS_ftell(m_hFile);
+ int32_t iLen = std::min((m_iLength - iPosition) / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ iLen = FXSYS_fread(pStr, 2, iLen, m_hFile);
+ int32_t iCount = 0;
+ while (*pStr != L'\0' && iCount < iLen) {
+ pStr++, iCount++;
+ }
+ iPosition += iCount * 2;
+ if (FXSYS_ftell(m_hFile) != iPosition) {
+ FXSYS_fseek(m_hFile, iPosition, 0);
+ }
+ bEOS = (iPosition >= m_iLength);
+ return iCount;
+}
+int32_t CFX_FileStreamImp::WriteData(const uint8_t* pBuffer,
+ int32_t iBufferSize) {
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ int32_t iRet = FXSYS_fwrite(pBuffer, 1, iBufferSize, m_hFile);
+ if (iRet != 0) {
+ int32_t iPos = FXSYS_ftell(m_hFile);
+ if (iPos > m_iLength) {
+ m_iLength = iPos;
+ }
+ }
+ return iRet;
+}
+int32_t CFX_FileStreamImp::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ int32_t iRet = FXSYS_fwrite(pStr, 2, iLength, m_hFile);
+ if (iRet != 0) {
+ int32_t iPos = FXSYS_ftell(m_hFile);
+ if (iPos > m_iLength) {
+ m_iLength = iPos;
+ }
+ }
+ return iRet;
+}
+void CFX_FileStreamImp::Flush() {
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_fflush(m_hFile);
+}
+FX_BOOL CFX_FileStreamImp::SetLength(int32_t iLength) {
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FX_BOOL bRet = FX_fsetsize(m_hFile, iLength);
+ m_iLength = FX_filelength(m_hFile);
+ return bRet;
+}
+CFX_FileReadStreamImp::CFX_FileReadStreamImp()
+ : m_pFileRead(NULL), m_iPosition(0), m_iLength(0) {}
+FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead* pFileRead,
+ FX_DWORD dwAccess) {
+ FXSYS_assert(m_pFileRead == NULL && pFileRead != NULL);
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ return FALSE;
+ }
+ m_pFileRead = pFileRead;
+ m_iLength = m_pFileRead->GetSize();
+ return TRUE;
+}
+int32_t CFX_FileReadStreamImp::GetLength() const {
+ return m_iLength;
+}
+int32_t CFX_FileReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = m_iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= m_iLength) {
+ m_iPosition = m_iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_FileReadStreamImp::IsEOF() const {
+ return m_iPosition >= m_iLength;
+}
+int32_t CFX_FileReadStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+ FXSYS_assert(m_pFileRead != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (iBufferSize > m_iLength - m_iPosition) {
+ iBufferSize = m_iLength - m_iPosition;
+ }
+ if (m_pFileRead->ReadBlock(pBuffer, m_iPosition, iBufferSize)) {
+ m_iPosition += iBufferSize;
+ return iBufferSize;
+ }
+ return 0;
+}
+int32_t CFX_FileReadStreamImp::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) {
+ FXSYS_assert(m_pFileRead != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2;
+ if (iMaxLength <= 0) {
+ return 0;
+ }
+ int32_t i = 0;
+ while (i < iMaxLength && pStr[i] != L'\0') {
+ ++i;
+ }
+ bEOS = (m_iPosition >= m_iLength) || pStr[i] == L'\0';
+ return i;
+}
+CFX_BufferReadStreamImp::CFX_BufferReadStreamImp()
+ : m_pBufferRead(NULL),
+ m_bReleaseBufferRead(FALSE),
+ m_iPosition(0),
+ m_iBufferSize(0) {}
+CFX_BufferReadStreamImp::~CFX_BufferReadStreamImp() {
+ if (m_bReleaseBufferRead && m_pBufferRead != NULL) {
+ m_pBufferRead->Release();
+ }
+}
+FX_BOOL CFX_BufferReadStreamImp::LoadBufferRead(IFX_BufferRead* pBufferRead,
+ int32_t iFileSize,
+ FX_DWORD dwAccess,
+ FX_BOOL bReleaseBufferRead) {
+ FXSYS_assert(m_pBufferRead == NULL && pBufferRead != NULL);
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ return FALSE;
+ }
+ m_bReleaseBufferRead = bReleaseBufferRead;
+ m_pBufferRead = pBufferRead;
+ m_iBufferSize = iFileSize;
+ if (m_iBufferSize >= 0) {
+ return TRUE;
+ }
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return FALSE;
+ }
+ m_iBufferSize = m_pBufferRead->GetBlockSize();
+ while (!m_pBufferRead->IsEOF()) {
+ m_pBufferRead->ReadNextBlock(FALSE);
+ m_iBufferSize += m_pBufferRead->GetBlockSize();
+ }
+ return TRUE;
+}
+int32_t CFX_BufferReadStreamImp::GetLength() const {
+ return m_iBufferSize;
+}
+int32_t CFX_BufferReadStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ int32_t iLength = GetLength();
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= iLength) {
+ m_iPosition = iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_BufferReadStreamImp::IsEOF() const {
+ return m_pBufferRead ? m_pBufferRead->IsEOF() : TRUE;
+}
+int32_t CFX_BufferReadStreamImp::ReadData(uint8_t* pBuffer,
+ int32_t iBufferSize) {
+ FXSYS_assert(m_pBufferRead != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ int32_t iLength = GetLength();
+ if (m_iPosition >= iLength) {
+ return 0;
+ }
+ if (iBufferSize > iLength - m_iPosition) {
+ iBufferSize = iLength - m_iPosition;
+ }
+ FX_DWORD dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ FX_DWORD dwBlockSize = m_pBufferRead->GetBlockSize();
+ if (m_iPosition < (int32_t)dwBlockOffset) {
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return 0;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ }
+ while (m_iPosition < (int32_t)dwBlockOffset ||
+ m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) {
+ if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ }
+ if (m_iPosition < (int32_t)dwBlockOffset ||
+ m_iPosition >= (int32_t)(dwBlockOffset + dwBlockSize)) {
+ return 0;
+ }
+ const uint8_t* pBufferTmp = m_pBufferRead->GetBlockBuffer();
+ FX_DWORD dwOffsetTmp = m_iPosition - dwBlockOffset;
+ FX_DWORD dwCopySize =
+ std::min(iBufferSize, (int32_t)(dwBlockSize - dwOffsetTmp));
+ FXSYS_memcpy(pBuffer, pBufferTmp + dwOffsetTmp, dwCopySize);
+ dwOffsetTmp = dwCopySize;
+ iBufferSize -= dwCopySize;
+ while (iBufferSize > 0) {
+ if (!m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ pBufferTmp = m_pBufferRead->GetBlockBuffer();
+ dwCopySize = std::min((FX_DWORD)iBufferSize, dwBlockSize);
+ FXSYS_memcpy(pBuffer + dwOffsetTmp, pBufferTmp, dwCopySize);
+ dwOffsetTmp += dwCopySize;
+ iBufferSize -= dwCopySize;
+ }
+ m_iPosition += dwOffsetTmp;
+ return dwOffsetTmp;
+}
+int32_t CFX_BufferReadStreamImp::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) {
+ FXSYS_assert(m_pBufferRead != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ iMaxLength = ReadData((uint8_t*)pStr, iMaxLength * 2) / 2;
+ if (iMaxLength <= 0) {
+ return 0;
+ }
+ int32_t i = 0;
+ while (i < iMaxLength && pStr[i] != L'\0') {
+ ++i;
+ }
+ bEOS = (m_iPosition >= GetLength()) || pStr[i] == L'\0';
+ return i;
+}
+CFX_FileWriteStreamImp::CFX_FileWriteStreamImp()
+ : m_pFileWrite(NULL), m_iPosition(0) {}
+FX_BOOL CFX_FileWriteStreamImp::LoadFileWrite(IFX_FileWrite* pFileWrite,
+ FX_DWORD dwAccess) {
+ FXSYS_assert(m_pFileWrite == NULL && pFileWrite != NULL);
+ if (dwAccess & FX_STREAMACCESS_Read) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ m_iPosition = pFileWrite->GetSize();
+ }
+ m_pFileWrite = pFileWrite;
+ return TRUE;
+}
+int32_t CFX_FileWriteStreamImp::GetLength() const {
+ if (!m_pFileWrite) {
+ return 0;
+ }
+ return (int32_t)m_pFileWrite->GetSize();
+}
+int32_t CFX_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ int32_t iLength = GetLength();
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= iLength) {
+ m_iPosition = iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_FileWriteStreamImp::IsEOF() const {
+ return m_iPosition >= GetLength();
+}
+int32_t CFX_FileWriteStreamImp::WriteData(const uint8_t* pBuffer,
+ int32_t iBufferSize) {
+ if (!m_pFileWrite) {
+ return 0;
+ }
+ if (m_pFileWrite->WriteBlock(pBuffer, m_iPosition, iBufferSize)) {
+ m_iPosition += iBufferSize;
+ }
+ return iBufferSize;
+}
+int32_t CFX_FileWriteStreamImp::WriteString(const FX_WCHAR* pStr,
+ int32_t iLength) {
+ return WriteData((const uint8_t*)pStr, iLength * sizeof(FX_WCHAR));
+}
+void CFX_FileWriteStreamImp::Flush() {
+ if (m_pFileWrite) {
+ m_pFileWrite->Flush();
+ }
+}
+CFX_BufferStreamImp::CFX_BufferStreamImp()
+ : CFX_StreamImp(),
+ m_pData(NULL),
+ m_iTotalSize(0),
+ m_iPosition(0),
+ m_iLength(0) {}
+FX_BOOL CFX_BufferStreamImp::LoadBuffer(uint8_t* pData,
+ int32_t iTotalSize,
+ FX_DWORD dwAccess) {
+ FXSYS_assert(m_pData == NULL);
+ FXSYS_assert(pData != NULL && iTotalSize > 0);
+ m_dwAccess = dwAccess;
+ m_pData = pData;
+ m_iTotalSize = iTotalSize;
+ m_iPosition = 0;
+ m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iTotalSize;
+ return TRUE;
+}
+int32_t CFX_BufferStreamImp::GetLength() const {
+ FXSYS_assert(m_pData != NULL);
+ return m_iLength;
+}
+int32_t CFX_BufferStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ FXSYS_assert(m_pData != NULL);
+ if (eSeek == FX_STREAMSEEK_Begin) {
+ m_iPosition = iOffset;
+ } else if (eSeek == FX_STREAMSEEK_Current) {
+ m_iPosition += iOffset;
+ } else if (eSeek == FX_STREAMSEEK_End) {
+ m_iPosition = m_iLength + iOffset;
+ }
+ if (m_iPosition > m_iLength) {
+ m_iPosition = m_iLength;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ }
+ return m_iPosition;
+}
+int32_t CFX_BufferStreamImp::GetPosition() {
+ FXSYS_assert(m_pData != NULL);
+ return m_iPosition;
+}
+FX_BOOL CFX_BufferStreamImp::IsEOF() const {
+ FXSYS_assert(m_pData != NULL);
+ return m_iPosition >= m_iLength;
+}
+int32_t CFX_BufferStreamImp::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+ FXSYS_assert(m_pData != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ int32_t iLen = std::min(m_iLength - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(pBuffer, m_pData + m_iPosition, iLen);
+ m_iPosition += iLen;
+ return iLen;
+}
+int32_t CFX_BufferStreamImp::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) {
+ FXSYS_assert(m_pData != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ int32_t iLen = std::min((m_iLength - m_iPosition) / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ const FX_WCHAR* pSrc = (const FX_WCHAR*)(FX_CHAR*)(m_pData + m_iPosition);
+ int32_t iCount = 0;
+ while (*pSrc != L'\0' && iCount < iLen) {
+ *pStr++ = *pSrc++, iCount++;
+ }
+ m_iPosition += iCount * 2;
+ bEOS = (*pSrc == L'\0') || (m_iPosition >= m_iLength);
+ return iCount;
+}
+int32_t CFX_BufferStreamImp::WriteData(const uint8_t* pBuffer,
+ int32_t iBufferSize) {
+ FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ int32_t iLen = std::min(m_iTotalSize - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(m_pData + m_iPosition, pBuffer, iLen);
+ m_iPosition += iLen;
+ if (m_iPosition > m_iLength) {
+ m_iLength = m_iPosition;
+ }
+ return iLen;
+}
+int32_t CFX_BufferStreamImp::WriteString(const FX_WCHAR* pStr,
+ int32_t iLength) {
+ FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ int32_t iLen = std::min((m_iTotalSize - m_iPosition) / 2, iLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(m_pData + m_iPosition, pStr, iLen * 2);
+ m_iPosition += iLen * 2;
+ if (m_iPosition > m_iLength) {
+ m_iLength = m_iPosition;
+ }
+ return iLen;
+}
+IFX_Stream* IFX_Stream::CreateTextStream(IFX_Stream* pBaseStream,
+ FX_BOOL bDeleteOnRelease) {
+ FXSYS_assert(pBaseStream != NULL);
+ return new CFX_TextStream(pBaseStream, bDeleteOnRelease);
+}
+CFX_TextStream::CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream)
+ : m_wCodePage(FX_CODEPAGE_DefANSI),
+ m_wBOMLength(0),
+ m_dwBOM(0),
+ m_pBuf(NULL),
+ m_iBufSize(0),
+ m_bDelStream(bDelStream),
+ m_pStreamImp(pStream),
+ m_iRefCount(1) {
+ FXSYS_assert(m_pStreamImp != NULL);
+ m_pStreamImp->Retain();
+ InitStream();
+}
+CFX_TextStream::~CFX_TextStream() {
+ m_pStreamImp->Release();
+ if (m_bDelStream) {
+ m_pStreamImp->Release();
+ }
+ if (m_pBuf != NULL) {
+ FX_Free(m_pBuf);
+ }
+}
+void CFX_TextStream::InitStream() {
+ int32_t iPosition = m_pStreamImp->GetPosition();
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, 0);
+ m_pStreamImp->ReadData((uint8_t*)&m_dwBOM, 3);
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ m_dwBOM &= 0x00FFFFFF;
+ if (m_dwBOM == 0x00BFBBEF) {
+ m_wBOMLength = 3;
+ m_wCodePage = FX_CODEPAGE_UTF8;
+ } else {
+ m_dwBOM &= 0x0000FFFF;
+ if (m_dwBOM == 0x0000FFFE) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16BE;
+ } else if (m_dwBOM == 0x0000FEFF) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16LE;
+ } else {
+ m_wBOMLength = 0;
+ m_dwBOM = 0;
+ m_wCodePage = FXSYS_GetACP();
+ }
+ }
+#else
+ m_dwBOM &= 0xFFFFFF00;
+ if (m_dwBOM == 0xEFBBBF00) {
+ m_wBOMLength = 3;
+ m_wCodePage = FX_CODEPAGE_UTF8;
+ } else {
+ m_dwBOM &= 0xFFFF0000;
+ if (m_dwBOM == 0xFEFF0000) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16BE;
+ } else if (m_dwBOM == 0xFFFE0000) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16LE;
+ } else {
+ m_wBOMLength = 0;
+ m_dwBOM = 0;
+ m_wCodePage = FXSYS_GetACP();
+ }
+ }
+#endif
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, std::max(m_wBOMLength, iPosition));
+}
+void CFX_TextStream::Release() {
+ if (--m_iRefCount < 1) {
+ delete this;
+ }
+}
+IFX_Stream* CFX_TextStream::Retain() {
+ m_iRefCount++;
+ return this;
+}
+FX_DWORD CFX_TextStream::GetAccessModes() const {
+ return m_pStreamImp->GetAccessModes() | FX_STREAMACCESS_Text;
+}
+int32_t CFX_TextStream::GetLength() const {
+ return m_pStreamImp->GetLength();
+}
+int32_t CFX_TextStream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ return m_pStreamImp->Seek(eSeek, iOffset);
+}
+int32_t CFX_TextStream::GetPosition() {
+ return m_pStreamImp->GetPosition();
+}
+FX_BOOL CFX_TextStream::IsEOF() const {
+ return m_pStreamImp->IsEOF();
+}
+int32_t CFX_TextStream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+ return m_pStreamImp->ReadData(pBuffer, iBufferSize);
+}
+int32_t CFX_TextStream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
+ return m_pStreamImp->WriteData(pBuffer, iBufferSize);
+}
+void CFX_TextStream::Flush() {
+ m_pStreamImp->Flush();
+}
+FX_BOOL CFX_TextStream::SetLength(int32_t iLength) {
+ return m_pStreamImp->SetLength(iLength);
+}
+FX_WORD CFX_TextStream::GetCodePage() const {
+ return m_wCodePage;
+}
+IFX_Stream* CFX_TextStream::CreateSharedStream(FX_DWORD dwAccess,
+ int32_t iOffset,
+ int32_t iLength) {
+ IFX_Stream* pSR =
+ m_pStreamImp->CreateSharedStream(dwAccess, iOffset, iLength);
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return new CFX_TextStream(pSR, TRUE);
+ }
+ return pSR;
+}
+int32_t CFX_TextStream::GetBOM(uint8_t bom[4]) const {
+ if (m_wBOMLength < 1) {
+ return 0;
+ }
+ *(FX_DWORD*)bom = m_dwBOM;
+ return m_wBOMLength;
+}
+FX_WORD CFX_TextStream::SetCodePage(FX_WORD wCodePage) {
+ if (m_wBOMLength > 0) {
+ return m_wCodePage;
+ }
+ FX_WORD v = m_wCodePage;
+ m_wCodePage = wCodePage;
+ return v;
+}
+int32_t CFX_TextStream::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS,
+ int32_t const* pByteSize) {
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ int32_t iLen;
+ if (m_wCodePage == FX_CODEPAGE_UTF16LE ||
+ m_wCodePage == FX_CODEPAGE_UTF16BE) {
+ int32_t iBytes = pByteSize == NULL ? iMaxLength * 2 : *pByteSize;
+ m_pStreamImp->Lock();
+ iLen = m_pStreamImp->ReadData((uint8_t*)pStr, iBytes);
+ m_pStreamImp->Unlock();
+ iMaxLength = iLen / 2;
+ if (sizeof(FX_WCHAR) > 2) {
+ FX_UTF16ToWChar(pStr, iMaxLength);
+ }
+#if _FX_ENDIAN_ == _FX_BIG_ENDIAN_
+ if (m_wCodePage == FX_CODEPAGE_UTF16LE) {
+ FX_SwapByteOrder(pStr, iMaxLength);
+ }
+#else
+ if (m_wCodePage == FX_CODEPAGE_UTF16BE) {
+ FX_SwapByteOrder(pStr, iMaxLength);
+ }
+#endif
+ } else {
+ int32_t pos = m_pStreamImp->GetPosition();
+ int32_t iBytes = pByteSize == NULL ? iMaxLength : *pByteSize;
+ iBytes = std::min(iBytes, m_pStreamImp->GetLength() - pos);
+ if (iBytes > 0) {
+ if (m_pBuf == NULL) {
+ m_pBuf = FX_Alloc(uint8_t, iBytes);
+ m_iBufSize = iBytes;
+ } else if (iBytes > m_iBufSize) {
+ m_pBuf = FX_Realloc(uint8_t, m_pBuf, iBytes);
+ m_iBufSize = iBytes;
+ }
+ m_pStreamImp->Lock();
+ iLen = m_pStreamImp->ReadData(m_pBuf, iBytes);
+ int32_t iSrc = iLen;
+ int32_t iDecode = FX_DecodeString(m_wCodePage, (const FX_CHAR*)m_pBuf,
+ &iSrc, pStr, &iMaxLength, TRUE);
+ m_pStreamImp->Seek(FX_STREAMSEEK_Current, iSrc - iLen);
+ m_pStreamImp->Unlock();
+ if (iDecode < 1) {
+ return -1;
+ }
+ } else {
+ iMaxLength = 0;
+ }
+ }
+ bEOS = m_pStreamImp->IsEOF();
+ return iMaxLength;
+}
+int32_t CFX_TextStream::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ if ((m_pStreamImp->GetAccessModes() & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ if (m_wCodePage == FX_CODEPAGE_UTF8) {
+ int32_t len = iLength;
+ CFX_UTF8Encoder encoder;
+ while (len-- > 0) {
+ encoder.Input(*pStr++);
+ }
+ CFX_ByteStringC bsResult = encoder.GetResult();
+ m_pStreamImp->Lock();
+ m_pStreamImp->WriteData((const uint8_t*)bsResult.GetCStr(),
+ bsResult.GetLength());
+ m_pStreamImp->Unlock();
+ }
+ return iLength;
+}
+CFX_Stream::CFX_Stream()
+ : m_eStreamType(FX_SREAMTYPE_Unknown),
+ m_pStreamImp(NULL),
+ m_dwAccess(0),
+ m_iTotalSize(0),
+ m_iPosition(0),
+ m_iStart(0),
+ m_iLength(0),
+ m_iRefCount(1) {}
+CFX_Stream::~CFX_Stream() {
+ if (m_eStreamType != FX_STREAMTYPE_Stream && m_pStreamImp != NULL) {
+ m_pStreamImp->Release();
+ }
+}
+FX_BOOL CFX_Stream::LoadFile(const FX_WCHAR* pszSrcFileName,
+ FX_DWORD dwAccess) {
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pszSrcFileName == NULL || FXSYS_wcslen(pszSrcFileName) < 1) {
+ return FALSE;
+ }
+ m_pStreamImp = new CFX_FileStreamImp();
+ FX_BOOL bRet =
+ ((CFX_FileStreamImp*)m_pStreamImp)->LoadFile(pszSrcFileName, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess) {
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pFileRead == NULL) {
+ return FALSE;
+ }
+ m_pStreamImp = new CFX_FileReadStreamImp();
+ FX_BOOL bRet =
+ ((CFX_FileReadStreamImp*)m_pStreamImp)->LoadFileRead(pFileRead, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadFileWrite(IFX_FileWrite* pFileWrite,
+ FX_DWORD dwAccess) {
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pFileWrite == NULL) {
+ return FALSE;
+ }
+ m_pStreamImp = new CFX_FileWriteStreamImp();
+ FX_BOOL bRet = ((CFX_FileWriteStreamImp*)m_pStreamImp)
+ ->LoadFileWrite(pFileWrite, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadBuffer(uint8_t* pData,
+ int32_t iTotalSize,
+ FX_DWORD dwAccess) {
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pData == NULL || iTotalSize < 1) {
+ return FALSE;
+ }
+ m_pStreamImp = new CFX_BufferStreamImp();
+ FX_BOOL bRet = ((CFX_BufferStreamImp*)m_pStreamImp)
+ ->LoadBuffer(pData, iTotalSize, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_Buffer;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadBufferRead(IFX_BufferRead* pBufferRead,
+ int32_t iFileSize,
+ FX_DWORD dwAccess,
+ FX_BOOL bReleaseBufferRead) {
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (!pBufferRead) {
+ return FALSE;
+ }
+ m_pStreamImp = new CFX_BufferReadStreamImp;
+ FX_BOOL bRet = ((CFX_BufferReadStreamImp*)m_pStreamImp)
+ ->LoadBufferRead(pBufferRead, iFileSize, dwAccess,
+ bReleaseBufferRead);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_BufferRead;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+void CFX_Stream::Release() {
+ if (--m_iRefCount < 1) {
+ delete this;
+ }
+}
+IFX_Stream* CFX_Stream::Retain() {
+ m_iRefCount++;
+ return this;
+}
+int32_t CFX_Stream::GetLength() const {
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File ||
+ m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_pStreamImp->GetLength();
+ }
+ return m_iLength;
+}
+int32_t CFX_Stream::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File ||
+ m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_iPosition = m_pStreamImp->Seek(eSeek, iOffset);
+ }
+ int32_t iEnd = m_iStart + m_iLength;
+ int32_t iPosition = m_iStart + iOffset;
+ if (eSeek == FX_STREAMSEEK_Begin) {
+ m_iPosition = iPosition;
+ } else if (eSeek == FX_STREAMSEEK_Current) {
+ m_iPosition += iOffset;
+ } else if (eSeek == FX_STREAMSEEK_End) {
+ m_iPosition = iEnd + iOffset;
+ }
+ if (m_iPosition > iEnd) {
+ m_iPosition = iEnd;
+ }
+ if (m_iPosition < m_iStart) {
+ m_iPosition = m_iStart;
+ }
+ return m_iPosition - m_iStart;
+}
+int32_t CFX_Stream::GetPosition() {
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File ||
+ m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_iPosition = m_pStreamImp->GetPosition();
+ }
+ return m_iPosition - m_iStart;
+}
+FX_BOOL CFX_Stream::IsEOF() const {
+ if (m_pStreamImp == NULL) {
+ return TRUE;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File ||
+ m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_pStreamImp->IsEOF();
+ }
+ return m_iPosition >= m_iStart + m_iLength;
+}
+int32_t CFX_Stream::ReadData(uint8_t* pBuffer, int32_t iBufferSize) {
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ int32_t iLen = std::min(m_iStart + m_iLength - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ m_pStreamImp->Lock();
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->ReadData(pBuffer, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+int32_t CFX_Stream::ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS,
+ int32_t const* pByteSize) {
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ int32_t iEnd = m_iStart + m_iLength;
+ int32_t iLen = iEnd - m_iPosition;
+ if (pByteSize != NULL) {
+ iLen = std::min(iLen, *pByteSize);
+ }
+ iLen = std::min(iEnd / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ m_pStreamImp->Lock();
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->ReadString(pStr, iLen, bEOS);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (iLen > 0 && m_iPosition >= iEnd) {
+ bEOS = TRUE;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+int32_t CFX_Stream::WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ int32_t iLen = iBufferSize;
+ if (m_eStreamType == FX_STREAMTYPE_Stream) {
+ iLen = std::min(m_iStart + m_iTotalSize - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ }
+ m_pStreamImp->Lock();
+ int32_t iEnd = m_iStart + m_iLength;
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->WriteData(pBuffer, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (m_iPosition > iEnd) {
+ m_iLength = m_iPosition - m_iStart;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+int32_t CFX_Stream::WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ int32_t iLen = iLength;
+ if (m_eStreamType == FX_STREAMTYPE_Stream) {
+ iLen = std::min((m_iStart + m_iTotalSize - m_iPosition) / 2, iLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ }
+ m_pStreamImp->Lock();
+ int32_t iEnd = m_iStart + m_iLength;
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->WriteString(pStr, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (m_iPosition > iEnd) {
+ m_iLength = m_iPosition - m_iStart;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+void CFX_Stream::Flush() {
+ if (m_pStreamImp == NULL) {
+ return;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return;
+ }
+ m_pStreamImp->Flush();
+}
+FX_BOOL CFX_Stream::SetLength(int32_t iLength) {
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return FALSE;
+ }
+ return m_pStreamImp->SetLength(iLength);
+}
+int32_t CFX_Stream::GetBOM(uint8_t bom[4]) const {
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ return 0;
+}
+FX_WORD CFX_Stream::GetCodePage() const {
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ return FX_CODEPAGE_UTF16LE;
+#else
+ return FX_CODEPAGE_UTF16BE;
+#endif
+}
+FX_WORD CFX_Stream::SetCodePage(FX_WORD wCodePage) {
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ return FX_CODEPAGE_UTF16LE;
+#else
+ return FX_CODEPAGE_UTF16BE;
+#endif
+}
+IFX_Stream* CFX_Stream::CreateSharedStream(FX_DWORD dwAccess,
+ int32_t iOffset,
+ int32_t iLength) {
+ FXSYS_assert(iLength > 0);
+ if (m_pStreamImp == NULL) {
+ return NULL;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Text) != 0 &&
+ (dwAccess & FX_STREAMACCESS_Text) == 0) {
+ return NULL;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0 &&
+ (dwAccess & FX_STREAMACCESS_Write) != 0) {
+ return NULL;
+ }
+ int32_t iStart = m_iStart + iOffset;
+ int32_t iTotal = m_iStart + m_iLength;
+ if (iStart < m_iStart || iStart >= iTotal) {
+ return NULL;
+ }
+ int32_t iEnd = iStart + iLength;
+ if (iEnd < iStart || iEnd > iTotal) {
+ return NULL;
+ }
+ CFX_Stream* pShared = new CFX_Stream;
+ pShared->m_eStreamType = FX_STREAMTYPE_Stream;
+ pShared->m_pStreamImp = m_pStreamImp;
+ pShared->m_dwAccess = dwAccess;
+ pShared->m_iTotalSize = iLength;
+ pShared->m_iPosition = iStart;
+ pShared->m_iStart = iStart;
+ pShared->m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iLength;
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return IFX_Stream::CreateTextStream(pShared, TRUE);
+ }
+ return pShared;
+}
+IFX_FileRead* FX_CreateFileRead(IFX_Stream* pBaseStream,
+ FX_BOOL bReleaseStream) {
+ FXSYS_assert(pBaseStream != NULL);
+ return new CFGAS_FileRead(pBaseStream, bReleaseStream);
+}
+CFGAS_FileRead::CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream)
+ : m_bReleaseStream(bReleaseStream), m_pStream(pStream) {
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileRead::~CFGAS_FileRead() {
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_FILESIZE CFGAS_FileRead::GetSize() {
+ return (FX_FILESIZE)m_pStream->GetLength();
+}
+FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, (int32_t)offset);
+ int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size);
+ m_pStream->Unlock();
+ return iLen == (int32_t)size;
+}
+
+IFX_FileRead* FX_CreateFileRead(IFX_BufferRead* pBufferRead,
+ FX_FILESIZE iFileSize,
+ FX_BOOL bReleaseStream) {
+ if (!pBufferRead) {
+ return NULL;
+ }
+ return new CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream);
+}
+CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead* pBufferRead,
+ FX_FILESIZE iFileSize,
+ FX_BOOL bReleaseStream)
+ : m_pBufferRead(pBufferRead),
+ m_bReleaseStream(bReleaseStream),
+ m_iBufSize(iFileSize) {
+ FXSYS_assert(m_pBufferRead);
+}
+CFX_BufferAccImp::~CFX_BufferAccImp() {
+ if (m_bReleaseStream && m_pBufferRead) {
+ m_pBufferRead->Release();
+ }
+}
+FX_FILESIZE CFX_BufferAccImp::GetSize() {
+ if (!m_pBufferRead) {
+ return 0;
+ }
+ if (m_iBufSize >= 0) {
+ return m_iBufSize;
+ }
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return 0;
+ }
+ m_iBufSize = (FX_FILESIZE)m_pBufferRead->GetBlockSize();
+ while (!m_pBufferRead->IsEOF()) {
+ m_pBufferRead->ReadNextBlock(FALSE);
+ m_iBufSize += (FX_FILESIZE)m_pBufferRead->GetBlockSize();
+ }
+ return m_iBufSize;
+}
+FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer,
+ FX_FILESIZE offset,
+ size_t size) {
+ if (!m_pBufferRead) {
+ return FALSE;
+ }
+ if (!buffer || !size) {
+ return TRUE;
+ }
+ FX_FILESIZE dwBufSize = GetSize();
+ if (offset >= dwBufSize) {
+ return FALSE;
+ }
+ size_t dwBlockSize = m_pBufferRead->GetBlockSize();
+ FX_FILESIZE dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ if (offset < dwBlockOffset) {
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return FALSE;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ while (offset < dwBlockOffset ||
+ offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
+ if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ if (offset < dwBlockOffset ||
+ offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
+ return FALSE;
+ }
+ const uint8_t* pBuffer = m_pBufferRead->GetBlockBuffer();
+ const FX_FILESIZE dwOffset = offset - dwBlockOffset;
+ size_t dwCopySize =
+ std::min(size, static_cast<size_t>(dwBlockSize - dwOffset));
+ FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize);
+ offset = dwCopySize;
+ size -= dwCopySize;
+ while (size) {
+ if (!m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ pBuffer = m_pBufferRead->GetBlockBuffer();
+ dwCopySize = std::min(size, dwBlockSize);
+ FXSYS_memcpy(((uint8_t*)buffer) + offset, pBuffer, dwCopySize);
+ offset += dwCopySize;
+ size -= dwCopySize;
+ }
+ return TRUE;
+}
+
+IFX_FileWrite* FX_CreateFileWrite(IFX_Stream* pBaseStream,
+ FX_BOOL bReleaseStream) {
+ FXSYS_assert(pBaseStream != NULL);
+ return new CFGAS_FileWrite(pBaseStream, bReleaseStream);
+}
+
+CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream)
+ : m_pStream(pStream), m_bReleaseStream(bReleaseStream) {
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileWrite::~CFGAS_FileWrite() {
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_FILESIZE CFGAS_FileWrite::GetSize() {
+ return m_pStream->GetLength();
+}
+FX_BOOL CFGAS_FileWrite::Flush() {
+ m_pStream->Flush();
+ return TRUE;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, size_t size) {
+ return m_pStream->WriteData((const uint8_t*)pData, (int32_t)size) ==
+ (int32_t)size;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData,
+ FX_FILESIZE offset,
+ size_t size) {
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, offset);
+ int32_t iLen = m_pStream->WriteData((uint8_t*)pData, (int32_t)size);
+ m_pStream->Unlock();
+ return iLen == (int32_t)size;
+}
diff --git a/xfa/src/fgas/src/crt/fx_stream.h b/xfa/src/fgas/src/crt/fx_stream.h
index 2eef6e8ee8..122cda1e39 100644
--- a/xfa/src/fgas/src/crt/fx_stream.h
+++ b/xfa/src/fgas/src/crt/fx_stream.h
@@ -1,311 +1,311 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_STREAM_IMP
-#define _FX_STREAM_IMP
-class CFX_StreamImp;
-class CFX_FileStreamImp;
-class CFX_BufferStreamImp;
-class CFX_FileReadStreamImp;
-class CFX_BufferReadStreamImp;
-class CFX_FileWriteStreamImp;
-class CFX_Stream;
-class CFX_TextStream;
-class CFX_FileRead;
-class CFX_FileWrite;
-class CFX_BufferAccImp;
-class CFX_StreamImp : public CFX_ThreadLock {
- public:
- virtual void Release() { delete this; }
- virtual FX_DWORD GetAccessModes() const { return m_dwAccess; }
- virtual int32_t GetLength() const = 0;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset) = 0;
- virtual int32_t GetPosition() = 0;
- virtual FX_BOOL IsEOF() const = 0;
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) = 0;
- virtual int32_t ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) = 0;
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) = 0;
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) = 0;
- virtual void Flush() = 0;
- virtual FX_BOOL SetLength(int32_t iLength) = 0;
-
- protected:
- CFX_StreamImp();
- virtual ~CFX_StreamImp() {}
- FX_DWORD m_dwAccess;
-};
-class CFX_FileStreamImp : public CFX_StreamImp {
- public:
- CFX_FileStreamImp();
- virtual ~CFX_FileStreamImp();
- FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess);
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition();
- virtual FX_BOOL IsEOF() const;
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
- virtual void Flush();
- virtual FX_BOOL SetLength(int32_t iLength);
-
- protected:
- FXSYS_FILE* m_hFile;
- int32_t m_iLength;
-};
-class CFX_BufferStreamImp : public CFX_StreamImp {
- public:
- CFX_BufferStreamImp();
- virtual ~CFX_BufferStreamImp() {}
- FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess);
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition();
- virtual FX_BOOL IsEOF() const;
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
- virtual void Flush() {}
- virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
-
- protected:
- uint8_t* m_pData;
- int32_t m_iTotalSize;
- int32_t m_iPosition;
- int32_t m_iLength;
-};
-class CFX_FileReadStreamImp : public CFX_StreamImp {
- public:
- CFX_FileReadStreamImp();
- virtual ~CFX_FileReadStreamImp() {}
- FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess);
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition() { return m_iPosition; }
- virtual FX_BOOL IsEOF() const;
-
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
- return 0;
- }
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) {
- return 0;
- }
- virtual void Flush() {}
- virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
-
- protected:
- IFX_FileRead* m_pFileRead;
- int32_t m_iPosition;
- int32_t m_iLength;
-};
-class CFX_BufferReadStreamImp : public CFX_StreamImp {
- public:
- CFX_BufferReadStreamImp();
- ~CFX_BufferReadStreamImp();
- FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead,
- int32_t iFileSize,
- FX_DWORD dwAccess,
- FX_BOOL bReleaseBufferRead);
-
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition() { return m_iPosition; }
- virtual FX_BOOL IsEOF() const;
-
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
- return 0;
- }
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) {
- return 0;
- }
- virtual void Flush() {}
- virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
-
- private:
- IFX_BufferRead* m_pBufferRead;
- FX_BOOL m_bReleaseBufferRead;
- int32_t m_iPosition;
- int32_t m_iBufferSize;
-};
-class CFX_FileWriteStreamImp : public CFX_StreamImp {
- public:
- CFX_FileWriteStreamImp();
- virtual ~CFX_FileWriteStreamImp() {}
- FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess);
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition() { return m_iPosition; }
- virtual FX_BOOL IsEOF() const;
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) { return 0; }
- virtual int32_t ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS) {
- return 0;
- }
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
- virtual void Flush();
- virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
-
- protected:
- IFX_FileWrite* m_pFileWrite;
- int32_t m_iPosition;
-};
-enum FX_STREAMTYPE {
- FX_SREAMTYPE_Unknown = 0,
- FX_STREAMTYPE_File,
- FX_STREAMTYPE_Buffer,
- FX_STREAMTYPE_Stream,
- FX_STREAMTYPE_BufferRead,
-};
-class CFX_Stream : public IFX_Stream, public CFX_ThreadLock {
- public:
- CFX_Stream();
- ~CFX_Stream();
- FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess);
- FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess);
- FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess);
- FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess);
- FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead,
- int32_t iFileSize,
- FX_DWORD dwAccess,
- FX_BOOL bReleaseBufferRead);
- virtual void Release();
- virtual IFX_Stream* Retain();
- virtual FX_DWORD GetAccessModes() const { return m_dwAccess; }
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition();
- virtual FX_BOOL IsEOF() const;
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS,
- int32_t const* pByteSize = NULL);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
- virtual void Flush();
- virtual FX_BOOL SetLength(int32_t iLength);
- virtual int32_t GetBOM(uint8_t bom[4]) const;
- virtual FX_WORD GetCodePage() const;
- virtual FX_WORD SetCodePage(FX_WORD wCodePage);
- virtual void Lock() { CFX_ThreadLock::Lock(); }
- virtual void Unlock() { CFX_ThreadLock::Unlock(); }
- virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess,
- int32_t iOffset,
- int32_t iLength);
-
- protected:
- FX_STREAMTYPE m_eStreamType;
- CFX_StreamImp* m_pStreamImp;
- FX_DWORD m_dwAccess;
- int32_t m_iTotalSize;
- int32_t m_iPosition;
- int32_t m_iStart;
- int32_t m_iLength;
- int32_t m_iRefCount;
-};
-class CFX_TextStream : public IFX_Stream, public CFX_ThreadLock {
- public:
- CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream);
- ~CFX_TextStream();
- virtual void Release();
- virtual IFX_Stream* Retain();
-
- virtual FX_DWORD GetAccessModes() const;
- virtual int32_t GetLength() const;
- virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
- virtual int32_t GetPosition();
- virtual FX_BOOL IsEOF() const;
-
- virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t ReadString(FX_WCHAR* pStr,
- int32_t iMaxLength,
- FX_BOOL& bEOS,
- int32_t const* pByteSize = NULL);
- virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
- virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
- virtual void Flush();
- virtual FX_BOOL SetLength(int32_t iLength);
-
- virtual int32_t GetBOM(uint8_t bom[4]) const;
- virtual FX_WORD GetCodePage() const;
- virtual FX_WORD SetCodePage(FX_WORD wCodePage);
-
- virtual void Lock() { CFX_ThreadLock::Lock(); }
- virtual void Unlock() { CFX_ThreadLock::Unlock(); }
-
- virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess,
- int32_t iOffset,
- int32_t iLength);
-
- protected:
- FX_WORD m_wCodePage;
- int32_t m_wBOMLength;
- FX_DWORD m_dwBOM;
- uint8_t* m_pBuf;
- int32_t m_iBufSize;
- FX_BOOL m_bDelStream;
- IFX_Stream* m_pStreamImp;
- int32_t m_iRefCount;
- void InitStream();
-};
-
-class CFGAS_FileRead : public IFX_FileRead {
- public:
- CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream);
- virtual ~CFGAS_FileRead();
- virtual void Release() { delete this; }
- virtual FX_FILESIZE GetSize();
- virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
-
- protected:
- FX_BOOL m_bReleaseStream;
- IFX_Stream* m_pStream;
-};
-
-class CFX_BufferAccImp : public IFX_FileRead {
- public:
- CFX_BufferAccImp(IFX_BufferRead* pBufferRead,
- FX_FILESIZE iFileSize,
- FX_BOOL bReleaseStream);
- virtual ~CFX_BufferAccImp();
- virtual void Release() { delete this; }
- virtual FX_FILESIZE GetSize();
- virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
-
- protected:
- IFX_BufferRead* m_pBufferRead;
- FX_BOOL m_bReleaseStream;
- FX_FILESIZE m_iBufSize;
-};
-
-class CFGAS_FileWrite : public IFX_FileWrite {
- public:
- CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream);
- virtual ~CFGAS_FileWrite();
- virtual void Release() { delete this; }
- virtual FX_FILESIZE GetSize();
- virtual FX_BOOL Flush();
- virtual FX_BOOL WriteBlock(const void* pData, size_t size);
- virtual FX_BOOL WriteBlock(const void* pData,
- FX_FILESIZE offset,
- size_t size);
-
- protected:
- IFX_Stream* m_pStream;
- FX_BOOL m_bReleaseStream;
-};
-
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_STREAM_IMP
+#define _FX_STREAM_IMP
+class CFX_StreamImp;
+class CFX_FileStreamImp;
+class CFX_BufferStreamImp;
+class CFX_FileReadStreamImp;
+class CFX_BufferReadStreamImp;
+class CFX_FileWriteStreamImp;
+class CFX_Stream;
+class CFX_TextStream;
+class CFX_FileRead;
+class CFX_FileWrite;
+class CFX_BufferAccImp;
+class CFX_StreamImp : public CFX_ThreadLock {
+ public:
+ virtual void Release() { delete this; }
+ virtual FX_DWORD GetAccessModes() const { return m_dwAccess; }
+ virtual int32_t GetLength() const = 0;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset) = 0;
+ virtual int32_t GetPosition() = 0;
+ virtual FX_BOOL IsEOF() const = 0;
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) = 0;
+ virtual int32_t ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) = 0;
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) = 0;
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) = 0;
+ virtual void Flush() = 0;
+ virtual FX_BOOL SetLength(int32_t iLength) = 0;
+
+ protected:
+ CFX_StreamImp();
+ virtual ~CFX_StreamImp() {}
+ FX_DWORD m_dwAccess;
+};
+class CFX_FileStreamImp : public CFX_StreamImp {
+ public:
+ CFX_FileStreamImp();
+ virtual ~CFX_FileStreamImp();
+ FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess);
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(int32_t iLength);
+
+ protected:
+ FXSYS_FILE* m_hFile;
+ int32_t m_iLength;
+};
+class CFX_BufferStreamImp : public CFX_StreamImp {
+ public:
+ CFX_BufferStreamImp();
+ virtual ~CFX_BufferStreamImp() {}
+ FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess);
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
+
+ protected:
+ uint8_t* m_pData;
+ int32_t m_iTotalSize;
+ int32_t m_iPosition;
+ int32_t m_iLength;
+};
+class CFX_FileReadStreamImp : public CFX_StreamImp {
+ public:
+ CFX_FileReadStreamImp();
+ virtual ~CFX_FileReadStreamImp() {}
+ FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess);
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition() { return m_iPosition; }
+ virtual FX_BOOL IsEOF() const;
+
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
+ return 0;
+ }
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+ return 0;
+ }
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
+
+ protected:
+ IFX_FileRead* m_pFileRead;
+ int32_t m_iPosition;
+ int32_t m_iLength;
+};
+class CFX_BufferReadStreamImp : public CFX_StreamImp {
+ public:
+ CFX_BufferReadStreamImp();
+ ~CFX_BufferReadStreamImp();
+ FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead,
+ int32_t iFileSize,
+ FX_DWORD dwAccess,
+ FX_BOOL bReleaseBufferRead);
+
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition() { return m_iPosition; }
+ virtual FX_BOOL IsEOF() const;
+
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr, int32_t iMaxLength, FX_BOOL& bEOS);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
+ return 0;
+ }
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+ return 0;
+ }
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
+
+ private:
+ IFX_BufferRead* m_pBufferRead;
+ FX_BOOL m_bReleaseBufferRead;
+ int32_t m_iPosition;
+ int32_t m_iBufferSize;
+};
+class CFX_FileWriteStreamImp : public CFX_StreamImp {
+ public:
+ CFX_FileWriteStreamImp();
+ virtual ~CFX_FileWriteStreamImp() {}
+ FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess);
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition() { return m_iPosition; }
+ virtual FX_BOOL IsEOF() const;
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) { return 0; }
+ virtual int32_t ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS) {
+ return 0;
+ }
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
+
+ protected:
+ IFX_FileWrite* m_pFileWrite;
+ int32_t m_iPosition;
+};
+enum FX_STREAMTYPE {
+ FX_SREAMTYPE_Unknown = 0,
+ FX_STREAMTYPE_File,
+ FX_STREAMTYPE_Buffer,
+ FX_STREAMTYPE_Stream,
+ FX_STREAMTYPE_BufferRead,
+};
+class CFX_Stream : public IFX_Stream, public CFX_ThreadLock {
+ public:
+ CFX_Stream();
+ ~CFX_Stream();
+ FX_BOOL LoadFile(const FX_WCHAR* pszSrcFileName, FX_DWORD dwAccess);
+ FX_BOOL LoadBuffer(uint8_t* pData, int32_t iTotalSize, FX_DWORD dwAccess);
+ FX_BOOL LoadFileRead(IFX_FileRead* pFileRead, FX_DWORD dwAccess);
+ FX_BOOL LoadFileWrite(IFX_FileWrite* pFileWrite, FX_DWORD dwAccess);
+ FX_BOOL LoadBufferRead(IFX_BufferRead* pBufferRead,
+ int32_t iFileSize,
+ FX_DWORD dwAccess,
+ FX_BOOL bReleaseBufferRead);
+ virtual void Release();
+ virtual IFX_Stream* Retain();
+ virtual FX_DWORD GetAccessModes() const { return m_dwAccess; }
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS,
+ int32_t const* pByteSize = NULL);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(int32_t iLength);
+ virtual int32_t GetBOM(uint8_t bom[4]) const;
+ virtual FX_WORD GetCodePage() const;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+ virtual void Lock() { CFX_ThreadLock::Lock(); }
+ virtual void Unlock() { CFX_ThreadLock::Unlock(); }
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess,
+ int32_t iOffset,
+ int32_t iLength);
+
+ protected:
+ FX_STREAMTYPE m_eStreamType;
+ CFX_StreamImp* m_pStreamImp;
+ FX_DWORD m_dwAccess;
+ int32_t m_iTotalSize;
+ int32_t m_iPosition;
+ int32_t m_iStart;
+ int32_t m_iLength;
+ int32_t m_iRefCount;
+};
+class CFX_TextStream : public IFX_Stream, public CFX_ThreadLock {
+ public:
+ CFX_TextStream(IFX_Stream* pStream, FX_BOOL bDelStream);
+ ~CFX_TextStream();
+ virtual void Release();
+ virtual IFX_Stream* Retain();
+
+ virtual FX_DWORD GetAccessModes() const;
+ virtual int32_t GetLength() const;
+ virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+ virtual int32_t GetPosition();
+ virtual FX_BOOL IsEOF() const;
+
+ virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t ReadString(FX_WCHAR* pStr,
+ int32_t iMaxLength,
+ FX_BOOL& bEOS,
+ int32_t const* pByteSize = NULL);
+ virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize);
+ virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(int32_t iLength);
+
+ virtual int32_t GetBOM(uint8_t bom[4]) const;
+ virtual FX_WORD GetCodePage() const;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+
+ virtual void Lock() { CFX_ThreadLock::Lock(); }
+ virtual void Unlock() { CFX_ThreadLock::Unlock(); }
+
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess,
+ int32_t iOffset,
+ int32_t iLength);
+
+ protected:
+ FX_WORD m_wCodePage;
+ int32_t m_wBOMLength;
+ FX_DWORD m_dwBOM;
+ uint8_t* m_pBuf;
+ int32_t m_iBufSize;
+ FX_BOOL m_bDelStream;
+ IFX_Stream* m_pStreamImp;
+ int32_t m_iRefCount;
+ void InitStream();
+};
+
+class CFGAS_FileRead : public IFX_FileRead {
+ public:
+ CFGAS_FileRead(IFX_Stream* pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileRead();
+ virtual void Release() { delete this; }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+
+ protected:
+ FX_BOOL m_bReleaseStream;
+ IFX_Stream* m_pStream;
+};
+
+class CFX_BufferAccImp : public IFX_FileRead {
+ public:
+ CFX_BufferAccImp(IFX_BufferRead* pBufferRead,
+ FX_FILESIZE iFileSize,
+ FX_BOOL bReleaseStream);
+ virtual ~CFX_BufferAccImp();
+ virtual void Release() { delete this; }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+
+ protected:
+ IFX_BufferRead* m_pBufferRead;
+ FX_BOOL m_bReleaseStream;
+ FX_FILESIZE m_iBufSize;
+};
+
+class CFGAS_FileWrite : public IFX_FileWrite {
+ public:
+ CFGAS_FileWrite(IFX_Stream* pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileWrite();
+ virtual void Release() { delete this; }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL Flush();
+ virtual FX_BOOL WriteBlock(const void* pData, size_t size);
+ virtual FX_BOOL WriteBlock(const void* pData,
+ FX_FILESIZE offset,
+ size_t size);
+
+ protected:
+ IFX_Stream* m_pStream;
+ FX_BOOL m_bReleaseStream;
+};
+
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_system.cpp b/xfa/src/fgas/src/crt/fx_system.cpp
index 861d1177ad..b08236bb1d 100644
--- a/xfa/src/fgas/src/crt/fx_system.cpp
+++ b/xfa/src/fgas/src/crt/fx_system.cpp
@@ -1,229 +1,229 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
-#include <io.h>
-#elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_
-#include <sys/times.h>
-#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-FX_FLOAT FX_tan(FX_FLOAT a) {
- return (FX_FLOAT)tan(a);
-}
-FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x) {
- return FXSYS_log(x) / FXSYS_log(b);
-}
-FX_WCHAR* FX_wcsncpy(FX_WCHAR* dstStr, const FX_WCHAR* srcStr, size_t count) {
- FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0);
- for (size_t i = 0; i < count; ++i)
- if ((dstStr[i] = srcStr[i]) == L'\0') {
- break;
- }
- return dstStr;
-}
-int32_t FX_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count) {
- FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
- FX_WCHAR wch1 = 0, wch2 = 0;
- while (count-- > 0) {
- wch1 = (FX_WCHAR)FX_tolower(*s1++);
- wch2 = (FX_WCHAR)FX_tolower(*s2++);
- if (wch1 != wch2) {
- break;
- }
- }
- return wch1 - wch2;
-}
-int32_t FX_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count) {
- FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
- FX_CHAR ch1 = 0, ch2 = 0;
- while (count-- > 0) {
- ch1 = (FX_CHAR)FX_tolower(*s1++);
- ch2 = (FX_CHAR)FX_tolower(*s2++);
- if (ch1 != ch2) {
- break;
- }
- }
- return ch1 - ch2;
-}
-int32_t FX_filelength(FXSYS_FILE* file) {
- FXSYS_assert(file != NULL);
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
- return _filelength(_fileno(file));
-#else
- int32_t iPos = FXSYS_ftell(file);
- FXSYS_fseek(file, 0, FXSYS_SEEK_END);
- int32_t iLen = FXSYS_ftell(file);
- FXSYS_fseek(file, iPos, FXSYS_SEEK_SET);
- return iLen;
-#endif
-}
-FX_BOOL FX_fsetsize(FXSYS_FILE* file, int32_t size) {
- FXSYS_assert(file != NULL);
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
- return _chsize(_fileno(file), size) == 0;
-#elif _FX_OS_ == _FX_WIN32_MOBILE_
- HANDLE hFile = _fileno(file);
- FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT);
- ::SetFilePointer(hFile, size, 0, FILE_BEGIN);
- FX_BOOL bRet = ::SetEndOfFile(hFile);
- ::SetFilePointer(hFile, (int32_t)dwPos, 0, FILE_BEGIN);
- return bRet;
-#else
- return FALSE;
-#endif
-}
-FX_FLOAT FX_strtof(const FX_CHAR* pcsStr, int32_t iLength, int32_t* pUsedLen) {
- FXSYS_assert(pcsStr != NULL);
- if (iLength < 0) {
- iLength = FXSYS_strlen(pcsStr);
- }
- return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength,
- pUsedLen);
-}
-FX_FLOAT FX_wcstof(const FX_WCHAR* pwsStr, int32_t iLength, int32_t* pUsedLen) {
- FXSYS_assert(pwsStr != NULL);
- if (iLength < 0) {
- iLength = FXSYS_wcslen(pwsStr);
- }
- if (iLength == 0) {
- return 0.0f;
- }
- int32_t iUsedLen = 0;
- FX_BOOL bNegtive = FALSE;
- switch (pwsStr[iUsedLen]) {
- case '-':
- bNegtive = TRUE;
- case '+':
- iUsedLen++;
- break;
- }
- FX_FLOAT fValue = 0.0f;
- while (iUsedLen < iLength) {
- FX_WCHAR wch = pwsStr[iUsedLen];
- if (wch >= L'0' && wch <= L'9') {
- fValue = fValue * 10.0f + (wch - L'0');
- } else {
- break;
- }
- iUsedLen++;
- }
- if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {
- FX_FLOAT fPrecise = 0.1f;
- while (++iUsedLen < iLength) {
- FX_WCHAR wch = pwsStr[iUsedLen];
- if (wch >= L'0' && wch <= L'9') {
- fValue += (wch - L'0') * fPrecise;
- fPrecise *= 0.1f;
- } else {
- break;
- }
- }
- }
- if (pUsedLen) {
- *pUsedLen = iUsedLen;
- }
- return bNegtive ? -fValue : fValue;
-}
-void FX_memset(void* pBuf, int32_t iValue, size_t size) {
- FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0);
- FXSYS_assert((((size_t)pBuf) & 0x03) == 0);
- FX_DWORD* pStart = (FX_DWORD*)pBuf;
- FX_DWORD* pEnd = pStart + (size >> 2);
- while (pStart < pEnd) {
- *pStart++ = iValue;
- }
-}
-void FX_memcpy(void* pDst, const void* pSrc, size_t size) {
- FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0);
- FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0);
- FX_DWORD* pStart = (FX_DWORD*)pDst;
- FX_DWORD* pEnd = pStart + (size >> 2);
- FX_DWORD* pValue = (FX_DWORD*)pSrc;
- while (pStart < pEnd) {
- *pStart++ = *pValue++;
- }
-}
-FX_BOOL FX_IsRelativePath(const CFX_WideStringC& wsUrl) {
- int32_t iUrlLen = wsUrl.GetLength();
- if (iUrlLen == 0) {
- return TRUE;
- }
- for (int32_t i = std::min(5, iUrlLen) - 1; i >= 0; --i)
- if (wsUrl.GetAt(i) == ':') {
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL FX_JoinPath(const CFX_WideStringC& wsBasePath,
- const CFX_WideStringC& wsRelativePath,
- CFX_WideString& wsAbsolutePath) {
- if (!FX_IsRelativePath(wsRelativePath)) {
- wsAbsolutePath = wsRelativePath;
- return TRUE;
- }
- const FX_WCHAR* pRelStart = wsRelativePath.GetPtr();
- const FX_WCHAR* pRelEnd = pRelStart + wsRelativePath.GetLength();
- if (pRelStart < pRelEnd) {
- switch (*pRelStart) {
- case '#':
- wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath);
- return wsAbsolutePath.GetLength() > 0;
- case '/':
- case '\\':
- wsAbsolutePath = wsRelativePath;
- return wsAbsolutePath.GetLength() > 0;
- }
- }
- int32_t nBackCount = 0;
- for (;;) {
- if (pRelStart >= pRelEnd) {
- wsAbsolutePath = wsBasePath;
- return TRUE;
- }
- if (*pRelStart != '.') {
- break;
- }
- if (pRelStart + 1 < pRelEnd &&
- (pRelStart[1] == '/' || pRelStart[1] == '\\')) {
- pRelStart += 2;
- } else if (pRelStart + 2 < pRelEnd && pRelStart[1] == '.' &&
- (pRelStart[2] == '/' || pRelStart[2] == '\\')) {
- pRelStart += 3;
- nBackCount++;
- } else {
- return FALSE;
- }
- }
- const FX_WCHAR* pBaseStart = wsBasePath.GetPtr();
- const FX_WCHAR* pBaseEnd = pBaseStart + wsBasePath.GetLength();
- while (pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\')
- ;
- if (pBaseStart == pBaseEnd) {
- wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart);
- return wsAbsolutePath.GetLength() > 0;
- }
- while (nBackCount > 0) {
- if (pBaseStart >= (--pBaseEnd)) {
- return FALSE;
- } else if (*pBaseEnd == '/' || *pBaseEnd == '\\')
- if ((--nBackCount) <= 0) {
- break;
- }
- }
- wsAbsolutePath =
- CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1),
- CFX_WideStringC(pRelStart, pRelEnd - pRelStart));
- return wsAbsolutePath.GetLength() > 0;
-}
-#ifdef __cplusplus
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+#include <io.h>
+#elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_
+#include <sys/times.h>
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+FX_FLOAT FX_tan(FX_FLOAT a) {
+ return (FX_FLOAT)tan(a);
+}
+FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x) {
+ return FXSYS_log(x) / FXSYS_log(b);
+}
+FX_WCHAR* FX_wcsncpy(FX_WCHAR* dstStr, const FX_WCHAR* srcStr, size_t count) {
+ FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0);
+ for (size_t i = 0; i < count; ++i)
+ if ((dstStr[i] = srcStr[i]) == L'\0') {
+ break;
+ }
+ return dstStr;
+}
+int32_t FX_wcsnicmp(const FX_WCHAR* s1, const FX_WCHAR* s2, size_t count) {
+ FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
+ FX_WCHAR wch1 = 0, wch2 = 0;
+ while (count-- > 0) {
+ wch1 = (FX_WCHAR)FX_tolower(*s1++);
+ wch2 = (FX_WCHAR)FX_tolower(*s2++);
+ if (wch1 != wch2) {
+ break;
+ }
+ }
+ return wch1 - wch2;
+}
+int32_t FX_strnicmp(const FX_CHAR* s1, const FX_CHAR* s2, size_t count) {
+ FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
+ FX_CHAR ch1 = 0, ch2 = 0;
+ while (count-- > 0) {
+ ch1 = (FX_CHAR)FX_tolower(*s1++);
+ ch2 = (FX_CHAR)FX_tolower(*s2++);
+ if (ch1 != ch2) {
+ break;
+ }
+ }
+ return ch1 - ch2;
+}
+int32_t FX_filelength(FXSYS_FILE* file) {
+ FXSYS_assert(file != NULL);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+ return _filelength(_fileno(file));
+#else
+ int32_t iPos = FXSYS_ftell(file);
+ FXSYS_fseek(file, 0, FXSYS_SEEK_END);
+ int32_t iLen = FXSYS_ftell(file);
+ FXSYS_fseek(file, iPos, FXSYS_SEEK_SET);
+ return iLen;
+#endif
+}
+FX_BOOL FX_fsetsize(FXSYS_FILE* file, int32_t size) {
+ FXSYS_assert(file != NULL);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+ return _chsize(_fileno(file), size) == 0;
+#elif _FX_OS_ == _FX_WIN32_MOBILE_
+ HANDLE hFile = _fileno(file);
+ FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT);
+ ::SetFilePointer(hFile, size, 0, FILE_BEGIN);
+ FX_BOOL bRet = ::SetEndOfFile(hFile);
+ ::SetFilePointer(hFile, (int32_t)dwPos, 0, FILE_BEGIN);
+ return bRet;
+#else
+ return FALSE;
+#endif
+}
+FX_FLOAT FX_strtof(const FX_CHAR* pcsStr, int32_t iLength, int32_t* pUsedLen) {
+ FXSYS_assert(pcsStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_strlen(pcsStr);
+ }
+ return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength,
+ pUsedLen);
+}
+FX_FLOAT FX_wcstof(const FX_WCHAR* pwsStr, int32_t iLength, int32_t* pUsedLen) {
+ FXSYS_assert(pwsStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pwsStr);
+ }
+ if (iLength == 0) {
+ return 0.0f;
+ }
+ int32_t iUsedLen = 0;
+ FX_BOOL bNegtive = FALSE;
+ switch (pwsStr[iUsedLen]) {
+ case '-':
+ bNegtive = TRUE;
+ case '+':
+ iUsedLen++;
+ break;
+ }
+ FX_FLOAT fValue = 0.0f;
+ while (iUsedLen < iLength) {
+ FX_WCHAR wch = pwsStr[iUsedLen];
+ if (wch >= L'0' && wch <= L'9') {
+ fValue = fValue * 10.0f + (wch - L'0');
+ } else {
+ break;
+ }
+ iUsedLen++;
+ }
+ if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {
+ FX_FLOAT fPrecise = 0.1f;
+ while (++iUsedLen < iLength) {
+ FX_WCHAR wch = pwsStr[iUsedLen];
+ if (wch >= L'0' && wch <= L'9') {
+ fValue += (wch - L'0') * fPrecise;
+ fPrecise *= 0.1f;
+ } else {
+ break;
+ }
+ }
+ }
+ if (pUsedLen) {
+ *pUsedLen = iUsedLen;
+ }
+ return bNegtive ? -fValue : fValue;
+}
+void FX_memset(void* pBuf, int32_t iValue, size_t size) {
+ FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0);
+ FXSYS_assert((((size_t)pBuf) & 0x03) == 0);
+ FX_DWORD* pStart = (FX_DWORD*)pBuf;
+ FX_DWORD* pEnd = pStart + (size >> 2);
+ while (pStart < pEnd) {
+ *pStart++ = iValue;
+ }
+}
+void FX_memcpy(void* pDst, const void* pSrc, size_t size) {
+ FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0);
+ FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0);
+ FX_DWORD* pStart = (FX_DWORD*)pDst;
+ FX_DWORD* pEnd = pStart + (size >> 2);
+ FX_DWORD* pValue = (FX_DWORD*)pSrc;
+ while (pStart < pEnd) {
+ *pStart++ = *pValue++;
+ }
+}
+FX_BOOL FX_IsRelativePath(const CFX_WideStringC& wsUrl) {
+ int32_t iUrlLen = wsUrl.GetLength();
+ if (iUrlLen == 0) {
+ return TRUE;
+ }
+ for (int32_t i = std::min(5, iUrlLen) - 1; i >= 0; --i)
+ if (wsUrl.GetAt(i) == ':') {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL FX_JoinPath(const CFX_WideStringC& wsBasePath,
+ const CFX_WideStringC& wsRelativePath,
+ CFX_WideString& wsAbsolutePath) {
+ if (!FX_IsRelativePath(wsRelativePath)) {
+ wsAbsolutePath = wsRelativePath;
+ return TRUE;
+ }
+ const FX_WCHAR* pRelStart = wsRelativePath.GetPtr();
+ const FX_WCHAR* pRelEnd = pRelStart + wsRelativePath.GetLength();
+ if (pRelStart < pRelEnd) {
+ switch (*pRelStart) {
+ case '#':
+ wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath);
+ return wsAbsolutePath.GetLength() > 0;
+ case '/':
+ case '\\':
+ wsAbsolutePath = wsRelativePath;
+ return wsAbsolutePath.GetLength() > 0;
+ }
+ }
+ int32_t nBackCount = 0;
+ for (;;) {
+ if (pRelStart >= pRelEnd) {
+ wsAbsolutePath = wsBasePath;
+ return TRUE;
+ }
+ if (*pRelStart != '.') {
+ break;
+ }
+ if (pRelStart + 1 < pRelEnd &&
+ (pRelStart[1] == '/' || pRelStart[1] == '\\')) {
+ pRelStart += 2;
+ } else if (pRelStart + 2 < pRelEnd && pRelStart[1] == '.' &&
+ (pRelStart[2] == '/' || pRelStart[2] == '\\')) {
+ pRelStart += 3;
+ nBackCount++;
+ } else {
+ return FALSE;
+ }
+ }
+ const FX_WCHAR* pBaseStart = wsBasePath.GetPtr();
+ const FX_WCHAR* pBaseEnd = pBaseStart + wsBasePath.GetLength();
+ while (pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\')
+ ;
+ if (pBaseStart == pBaseEnd) {
+ wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart);
+ return wsAbsolutePath.GetLength() > 0;
+ }
+ while (nBackCount > 0) {
+ if (pBaseStart >= (--pBaseEnd)) {
+ return FALSE;
+ } else if (*pBaseEnd == '/' || *pBaseEnd == '\\')
+ if ((--nBackCount) <= 0) {
+ break;
+ }
+ }
+ wsAbsolutePath =
+ CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1),
+ CFX_WideStringC(pRelStart, pRelEnd - pRelStart));
+ return wsAbsolutePath.GetLength() > 0;
+}
+#ifdef __cplusplus
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_utils.cpp b/xfa/src/fgas/src/crt/fx_utils.cpp
index e8be0d8d5f..7f62eb0993 100644
--- a/xfa/src/fgas/src/crt/fx_utils.cpp
+++ b/xfa/src/fgas/src/crt/fx_utils.cpp
@@ -1,432 +1,432 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/include/fx_utl.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_utils.h"
-
-CFX_ThreadLock::CFX_ThreadLock() {
-}
-CFX_ThreadLock::~CFX_ThreadLock() {}
-void CFX_ThreadLock::Lock() {}
-void CFX_ThreadLock::Unlock() {}
-class FX_BASEARRAYDATA : public CFX_Target {
- public:
- FX_BASEARRAYDATA(int32_t growsize, int32_t blocksize)
- : iGrowSize(growsize),
- iBlockSize(blocksize),
- iTotalCount(0),
- iBlockCount(0),
- pBuffer(nullptr) {}
-
- ~FX_BASEARRAYDATA() { FX_Free(pBuffer); }
-
- int32_t iGrowSize;
- int32_t iBlockSize;
- int32_t iTotalCount;
- int32_t iBlockCount;
- uint8_t* pBuffer;
-};
-CFX_BaseArray::CFX_BaseArray(int32_t iGrowSize, int32_t iBlockSize) {
- FXSYS_assert(iGrowSize > 0 && iBlockSize > 0);
- m_pData = new FX_BASEARRAYDATA(iGrowSize, iBlockSize);
-}
-CFX_BaseArray::~CFX_BaseArray() {
- RemoveAll();
- delete m_pData;
-}
-int32_t CFX_BaseArray::GetSize() const {
- return m_pData->iBlockCount;
-}
-int32_t CFX_BaseArray::GetBlockSize() const {
- return m_pData->iBlockSize;
-}
-uint8_t* CFX_BaseArray::AddSpaceTo(int32_t index) {
- FXSYS_assert(index > -1);
- uint8_t*& pBuffer = m_pData->pBuffer;
- int32_t& iTotalCount = m_pData->iTotalCount;
- int32_t iBlockSize = m_pData->iBlockSize;
- if (index >= iTotalCount) {
- int32_t iGrowSize = m_pData->iGrowSize;
- iTotalCount = (index / iGrowSize + 1) * iGrowSize;
- int32_t iNewSize = iTotalCount * iBlockSize;
- if (!pBuffer) {
- pBuffer = FX_Alloc(uint8_t, iNewSize);
- } else {
- pBuffer = FX_Realloc(uint8_t, pBuffer, iNewSize);
- }
- }
- int32_t& iBlockCount = m_pData->iBlockCount;
- if (index >= iBlockCount) {
- iBlockCount = index + 1;
- }
- return pBuffer + index * iBlockSize;
-}
-uint8_t* CFX_BaseArray::GetAt(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_pData->iBlockCount);
- return m_pData->pBuffer + index * m_pData->iBlockSize;
-}
-uint8_t* CFX_BaseArray::GetBuffer() const {
- return m_pData->pBuffer;
-}
-int32_t CFX_BaseArray::Append(const CFX_BaseArray& src,
- int32_t iStart,
- int32_t iCount) {
- int32_t iBlockSize = m_pData->iBlockSize;
- FXSYS_assert(iBlockSize == src.m_pData->iBlockSize);
- int32_t& iBlockCount = m_pData->iBlockCount;
- int32_t iAdded = src.GetSize();
- FXSYS_assert(iStart > -1 && iStart < iAdded);
- if (iCount < 0) {
- iCount = iAdded;
- }
- if (iStart + iCount > iAdded) {
- iCount = iAdded - iStart;
- }
- if (iCount < 1) {
- return 0;
- }
- uint8_t* pDst = m_pData->pBuffer + iBlockCount * iBlockSize;
- AddSpaceTo(iBlockCount + iCount - 1);
- FX_memcpy(pDst, src.m_pData->pBuffer + iStart * iBlockSize,
- iCount * iBlockSize);
- return iCount;
-}
-int32_t CFX_BaseArray::Copy(const CFX_BaseArray& src,
- int32_t iStart,
- int32_t iCount) {
- int32_t iBlockSize = m_pData->iBlockSize;
- FXSYS_assert(iBlockSize == src.m_pData->iBlockSize);
- int32_t iCopied = src.GetSize();
- FXSYS_assert(iStart > -1 && iStart < iCopied);
- if (iCount < 0) {
- iCount = iCopied;
- }
- if (iStart + iCount > iCopied) {
- iCount = iCopied - iStart;
- }
- if (iCount < 1) {
- return 0;
- }
- RemoveAll(TRUE);
- AddSpaceTo(iCount - 1);
- FX_memcpy(m_pData->pBuffer, src.m_pData->pBuffer + iStart * iBlockSize,
- iCount * iBlockSize);
- return iCount;
-}
-int32_t CFX_BaseArray::RemoveLast(int32_t iCount) {
- int32_t& iBlockCount = m_pData->iBlockCount;
- if (iCount < 0 || iCount > iBlockCount) {
- iCount = iBlockCount;
- iBlockCount = 0;
- } else {
- iBlockCount -= iCount;
- }
- return iCount;
-}
-void CFX_BaseArray::RemoveAll(FX_BOOL bLeaveMemory) {
- if (!bLeaveMemory) {
- uint8_t*& pBuffer = m_pData->pBuffer;
- if (pBuffer != NULL) {
- FX_Free(pBuffer);
- pBuffer = NULL;
- }
- m_pData->iTotalCount = 0;
- }
- m_pData->iBlockCount = 0;
-}
-CFX_BaseMassArrayImp::CFX_BaseMassArrayImp(int32_t iChunkSize,
- int32_t iBlockSize)
- : m_iChunkSize(iChunkSize),
- m_iBlockSize(iBlockSize),
- m_iChunkCount(0),
- m_iBlockCount(0) {
- FXSYS_assert(m_iChunkSize > 0 && m_iBlockSize > 0);
- m_pData = new CFX_PtrArray;
- m_pData->SetSize(16);
-}
-CFX_BaseMassArrayImp::~CFX_BaseMassArrayImp() {
- RemoveAll();
- delete m_pData;
-}
-uint8_t* CFX_BaseMassArrayImp::AddSpaceTo(int32_t index) {
- FXSYS_assert(index > -1);
- uint8_t* pChunk;
- if (index < m_iBlockCount) {
- pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
- } else {
- int32_t iMemSize = m_iChunkSize * m_iBlockSize;
- while (TRUE) {
- if (index < m_iChunkCount * m_iChunkSize) {
- pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
- break;
- } else {
- pChunk = FX_Alloc(uint8_t, iMemSize);
- if (m_iChunkCount < m_pData->GetSize()) {
- m_pData->SetAt(m_iChunkCount, pChunk);
- } else {
- m_pData->Add(pChunk);
- }
- m_iChunkCount++;
- }
- }
- }
- FXSYS_assert(pChunk != NULL);
- m_iBlockCount = index + 1;
- return pChunk + (index % m_iChunkSize) * m_iBlockSize;
-}
-uint8_t* CFX_BaseMassArrayImp::GetAt(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_iBlockCount);
- uint8_t* pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
- FXSYS_assert(pChunk != NULL);
- return pChunk + (index % m_iChunkSize) * m_iBlockSize;
-}
-int32_t CFX_BaseMassArrayImp::Append(const CFX_BaseMassArrayImp& src,
- int32_t iStart,
- int32_t iCount) {
- FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
- int32_t iAdded = src.m_iBlockCount;
- FXSYS_assert(iStart > -1 && iStart < iAdded);
- if (iCount < 0) {
- iCount = iAdded;
- }
- if (iStart + iCount > iAdded) {
- iCount = iAdded - iStart;
- }
- if (iCount < 1) {
- return m_iBlockCount;
- }
- int32_t iBlockCount = m_iBlockCount;
- int32_t iTotal = m_iBlockCount + iCount;
- AddSpaceTo(iTotal - 1);
- Append(iBlockCount, src, iStart, iCount);
- return m_iBlockCount;
-}
-int32_t CFX_BaseMassArrayImp::Copy(const CFX_BaseMassArrayImp& src,
- int32_t iStart,
- int32_t iCount) {
- FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
- int32_t iCopied = src.m_iBlockCount;
- FXSYS_assert(iStart > -1);
- if (iStart >= iCopied) {
- return 0;
- }
- RemoveAll(TRUE);
- if (iCount < 0) {
- iCount = iCopied;
- }
- if (iStart + iCount > iCopied) {
- iCount = iCopied - iStart;
- }
- if (iCount < 1) {
- return 0;
- }
- if (m_iBlockCount < iCount) {
- AddSpaceTo(iCount - 1);
- }
- Append(0, src, iStart, iCount);
- return m_iBlockCount;
-}
-void CFX_BaseMassArrayImp::Append(int32_t iDstStart,
- const CFX_BaseMassArrayImp& src,
- int32_t iSrcStart,
- int32_t iSrcCount) {
- FXSYS_assert(iDstStart > -1 && m_iBlockSize == src.m_iBlockSize);
- int32_t iSrcTotal = src.m_iBlockCount;
- FXSYS_assert(iSrcTotal > 0 && m_iBlockCount >= iDstStart + iSrcCount);
- FXSYS_assert(iSrcStart > -1 && iSrcStart < iSrcTotal && iSrcCount > 0 &&
- iSrcStart + iSrcCount <= iSrcTotal);
- int32_t iDstChunkIndex = iDstStart / m_iChunkSize;
- int32_t iSrcChunkIndex = iSrcStart / src.m_iChunkSize;
- uint8_t* pDstChunk = (uint8_t*)GetAt(iDstStart);
- uint8_t* pSrcChunk = (uint8_t*)src.GetAt(iSrcStart);
- int32_t iDstChunkSize = m_iChunkSize - (iDstStart % m_iChunkSize);
- int32_t iSrcChunkSize = src.m_iChunkSize - (iSrcStart % src.m_iChunkSize);
- int32_t iCopySize =
- std::min(iSrcCount, std::min(iSrcChunkSize, iDstChunkSize));
- int32_t iCopyBytes = iCopySize * m_iBlockSize;
- while (iSrcCount > 0) {
- FXSYS_assert(pDstChunk != NULL && pSrcChunk != NULL);
- FXSYS_memcpy(pDstChunk, pSrcChunk, iCopyBytes);
- iSrcCount -= iCopySize;
- iSrcChunkSize -= iCopySize;
- if (iSrcChunkSize < 1) {
- iSrcChunkSize = src.m_iChunkSize;
- iSrcChunkIndex++;
- pSrcChunk = (uint8_t*)src.m_pData->GetAt(iSrcChunkIndex);
- } else {
- pSrcChunk += iCopyBytes;
- }
- iDstChunkSize -= iCopySize;
- if (iDstChunkSize < 1) {
- iDstChunkSize = m_iChunkSize;
- iDstChunkIndex++;
- pDstChunk = (uint8_t*)m_pData->GetAt(iDstChunkIndex);
- } else {
- pDstChunk += iCopyBytes;
- }
- iCopySize = std::min(iSrcCount, std::min(iSrcChunkSize, iDstChunkSize));
- iCopyBytes = iCopySize * m_iBlockSize;
- }
-}
-int32_t CFX_BaseMassArrayImp::RemoveLast(int32_t iCount) {
- if (iCount < 0 || iCount >= m_iBlockCount) {
- m_iBlockCount = 0;
- } else {
- m_iBlockCount -= iCount;
- }
- return m_iBlockCount;
-}
-void CFX_BaseMassArrayImp::RemoveAll(FX_BOOL bLeaveMemory) {
- if (bLeaveMemory) {
- m_iBlockCount = 0;
- return;
- }
- for (int32_t i = 0; i < m_iChunkCount; i++) {
- void* p = m_pData->GetAt(i);
- if (p == NULL) {
- continue;
- }
- FX_Free(p);
- }
- m_pData->RemoveAll();
- m_iChunkCount = 0;
- m_iBlockCount = 0;
-}
-CFX_BaseMassArray::CFX_BaseMassArray(int32_t iChunkSize, int32_t iBlockSize) {
- m_pData = new CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
-}
-CFX_BaseMassArray::~CFX_BaseMassArray() {
- delete m_pData;
-}
-int32_t CFX_BaseMassArray::GetSize() const {
- return m_pData->m_iBlockCount;
-}
-uint8_t* CFX_BaseMassArray::AddSpaceTo(int32_t index) {
- return m_pData->AddSpaceTo(index);
-}
-uint8_t* CFX_BaseMassArray::GetAt(int32_t index) const {
- return m_pData->GetAt(index);
-}
-int32_t CFX_BaseMassArray::Append(const CFX_BaseMassArray& src,
- int32_t iStart,
- int32_t iCount) {
- return m_pData->Append(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
-}
-int32_t CFX_BaseMassArray::Copy(const CFX_BaseMassArray& src,
- int32_t iStart,
- int32_t iCount) {
- return m_pData->Copy(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
-}
-int32_t CFX_BaseMassArray::RemoveLast(int32_t iCount) {
- return m_pData->RemoveLast(iCount);
-}
-void CFX_BaseMassArray::RemoveAll(FX_BOOL bLeaveMemory) {
- m_pData->RemoveAll(bLeaveMemory);
-}
-typedef struct _FX_BASEDISCRETEARRAYDATA {
- int32_t iBlockSize;
- int32_t iChunkSize;
- int32_t iChunkCount;
- CFX_PtrArray ChunkBuffer;
-} FX_BASEDISCRETEARRAYDATA, *FX_LPBASEDISCRETEARRAYDATA;
-typedef FX_BASEDISCRETEARRAYDATA const* FX_LPCBASEDISCRETEARRAYDATA;
-CFX_BaseDiscreteArray::CFX_BaseDiscreteArray(int32_t iChunkSize,
- int32_t iBlockSize) {
- FXSYS_assert(iChunkSize > 0 && iBlockSize > 0);
- FX_LPBASEDISCRETEARRAYDATA pData;
- m_pData = pData = new FX_BASEDISCRETEARRAYDATA;
- pData->ChunkBuffer.SetSize(16);
- pData->iChunkCount = 0;
- pData->iChunkSize = iChunkSize;
- pData->iBlockSize = iBlockSize;
-}
-CFX_BaseDiscreteArray::~CFX_BaseDiscreteArray() {
- RemoveAll();
- delete (FX_LPBASEDISCRETEARRAYDATA) m_pData;
-}
-uint8_t* CFX_BaseDiscreteArray::AddSpaceTo(int32_t index) {
- FXSYS_assert(index > -1);
- FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
- int32_t& iChunkCount = pData->iChunkCount;
- int32_t iChunkSize = pData->iChunkSize;
- uint8_t* pChunk = NULL;
- int32_t iChunk = index / iChunkSize;
- if (iChunk < iChunkCount) {
- pChunk = (uint8_t*)pData->ChunkBuffer.GetAt(iChunk);
- }
- if (!pChunk) {
- pChunk = FX_Alloc2D(uint8_t, iChunkSize, pData->iBlockSize);
- FXSYS_memset(pChunk, 0, iChunkSize * pData->iBlockSize);
- pData->ChunkBuffer.SetAtGrow(iChunk, pChunk);
- if (iChunkCount <= iChunk) {
- iChunkCount = iChunk + 1;
- }
- }
- return pChunk + (index % iChunkSize) * pData->iBlockSize;
-}
-uint8_t* CFX_BaseDiscreteArray::GetAt(int32_t index) const {
- FXSYS_assert(index > -1);
- FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
- int32_t iChunkSize = pData->iChunkSize;
- int32_t iChunk = index / iChunkSize;
- if (iChunk >= pData->iChunkCount) {
- return NULL;
- }
- uint8_t* pChunk = (uint8_t*)pData->ChunkBuffer.GetAt(iChunk);
- if (pChunk == NULL) {
- return NULL;
- }
- return pChunk + (index % iChunkSize) * pData->iBlockSize;
-}
-void CFX_BaseDiscreteArray::RemoveAll() {
- FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
- CFX_PtrArray& ChunkBuffer = pData->ChunkBuffer;
- int32_t& iChunkCount = pData->iChunkCount;
- for (int32_t i = 0; i < iChunkCount; i++) {
- void* p = ChunkBuffer.GetAt(i);
- if (p == NULL) {
- continue;
- }
- FX_Free(p);
- }
- ChunkBuffer.RemoveAll();
- iChunkCount = 0;
-}
-CFX_BaseStack::CFX_BaseStack(int32_t iChunkSize, int32_t iBlockSize) {
- m_pData = new CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
-}
-CFX_BaseStack::~CFX_BaseStack() {
- delete (CFX_BaseMassArrayImp*)m_pData;
-}
-uint8_t* CFX_BaseStack::Push() {
- return m_pData->AddSpace();
-}
-void CFX_BaseStack::Pop() {
- int32_t& iBlockCount = m_pData->m_iBlockCount;
- if (iBlockCount < 1) {
- return;
- }
- iBlockCount--;
-}
-uint8_t* CFX_BaseStack::GetTopElement() const {
- int32_t iSize = m_pData->m_iBlockCount;
- if (iSize < 1) {
- return NULL;
- }
- return m_pData->GetAt(iSize - 1);
-}
-int32_t CFX_BaseStack::GetSize() const {
- return m_pData->m_iBlockCount;
-}
-uint8_t* CFX_BaseStack::GetAt(int32_t index) const {
- return m_pData->GetAt(index);
-}
-void CFX_BaseStack::RemoveAll(FX_BOOL bLeaveMemory) {
- m_pData->RemoveAll(bLeaveMemory);
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/include/fx_utl.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_utils.h"
+
+CFX_ThreadLock::CFX_ThreadLock() {
+}
+CFX_ThreadLock::~CFX_ThreadLock() {}
+void CFX_ThreadLock::Lock() {}
+void CFX_ThreadLock::Unlock() {}
+class FX_BASEARRAYDATA : public CFX_Target {
+ public:
+ FX_BASEARRAYDATA(int32_t growsize, int32_t blocksize)
+ : iGrowSize(growsize),
+ iBlockSize(blocksize),
+ iTotalCount(0),
+ iBlockCount(0),
+ pBuffer(nullptr) {}
+
+ ~FX_BASEARRAYDATA() { FX_Free(pBuffer); }
+
+ int32_t iGrowSize;
+ int32_t iBlockSize;
+ int32_t iTotalCount;
+ int32_t iBlockCount;
+ uint8_t* pBuffer;
+};
+CFX_BaseArray::CFX_BaseArray(int32_t iGrowSize, int32_t iBlockSize) {
+ FXSYS_assert(iGrowSize > 0 && iBlockSize > 0);
+ m_pData = new FX_BASEARRAYDATA(iGrowSize, iBlockSize);
+}
+CFX_BaseArray::~CFX_BaseArray() {
+ RemoveAll();
+ delete m_pData;
+}
+int32_t CFX_BaseArray::GetSize() const {
+ return m_pData->iBlockCount;
+}
+int32_t CFX_BaseArray::GetBlockSize() const {
+ return m_pData->iBlockSize;
+}
+uint8_t* CFX_BaseArray::AddSpaceTo(int32_t index) {
+ FXSYS_assert(index > -1);
+ uint8_t*& pBuffer = m_pData->pBuffer;
+ int32_t& iTotalCount = m_pData->iTotalCount;
+ int32_t iBlockSize = m_pData->iBlockSize;
+ if (index >= iTotalCount) {
+ int32_t iGrowSize = m_pData->iGrowSize;
+ iTotalCount = (index / iGrowSize + 1) * iGrowSize;
+ int32_t iNewSize = iTotalCount * iBlockSize;
+ if (!pBuffer) {
+ pBuffer = FX_Alloc(uint8_t, iNewSize);
+ } else {
+ pBuffer = FX_Realloc(uint8_t, pBuffer, iNewSize);
+ }
+ }
+ int32_t& iBlockCount = m_pData->iBlockCount;
+ if (index >= iBlockCount) {
+ iBlockCount = index + 1;
+ }
+ return pBuffer + index * iBlockSize;
+}
+uint8_t* CFX_BaseArray::GetAt(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_pData->iBlockCount);
+ return m_pData->pBuffer + index * m_pData->iBlockSize;
+}
+uint8_t* CFX_BaseArray::GetBuffer() const {
+ return m_pData->pBuffer;
+}
+int32_t CFX_BaseArray::Append(const CFX_BaseArray& src,
+ int32_t iStart,
+ int32_t iCount) {
+ int32_t iBlockSize = m_pData->iBlockSize;
+ FXSYS_assert(iBlockSize == src.m_pData->iBlockSize);
+ int32_t& iBlockCount = m_pData->iBlockCount;
+ int32_t iAdded = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iAdded);
+ if (iCount < 0) {
+ iCount = iAdded;
+ }
+ if (iStart + iCount > iAdded) {
+ iCount = iAdded - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ uint8_t* pDst = m_pData->pBuffer + iBlockCount * iBlockSize;
+ AddSpaceTo(iBlockCount + iCount - 1);
+ FX_memcpy(pDst, src.m_pData->pBuffer + iStart * iBlockSize,
+ iCount * iBlockSize);
+ return iCount;
+}
+int32_t CFX_BaseArray::Copy(const CFX_BaseArray& src,
+ int32_t iStart,
+ int32_t iCount) {
+ int32_t iBlockSize = m_pData->iBlockSize;
+ FXSYS_assert(iBlockSize == src.m_pData->iBlockSize);
+ int32_t iCopied = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iCopied);
+ if (iCount < 0) {
+ iCount = iCopied;
+ }
+ if (iStart + iCount > iCopied) {
+ iCount = iCopied - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ AddSpaceTo(iCount - 1);
+ FX_memcpy(m_pData->pBuffer, src.m_pData->pBuffer + iStart * iBlockSize,
+ iCount * iBlockSize);
+ return iCount;
+}
+int32_t CFX_BaseArray::RemoveLast(int32_t iCount) {
+ int32_t& iBlockCount = m_pData->iBlockCount;
+ if (iCount < 0 || iCount > iBlockCount) {
+ iCount = iBlockCount;
+ iBlockCount = 0;
+ } else {
+ iBlockCount -= iCount;
+ }
+ return iCount;
+}
+void CFX_BaseArray::RemoveAll(FX_BOOL bLeaveMemory) {
+ if (!bLeaveMemory) {
+ uint8_t*& pBuffer = m_pData->pBuffer;
+ if (pBuffer != NULL) {
+ FX_Free(pBuffer);
+ pBuffer = NULL;
+ }
+ m_pData->iTotalCount = 0;
+ }
+ m_pData->iBlockCount = 0;
+}
+CFX_BaseMassArrayImp::CFX_BaseMassArrayImp(int32_t iChunkSize,
+ int32_t iBlockSize)
+ : m_iChunkSize(iChunkSize),
+ m_iBlockSize(iBlockSize),
+ m_iChunkCount(0),
+ m_iBlockCount(0) {
+ FXSYS_assert(m_iChunkSize > 0 && m_iBlockSize > 0);
+ m_pData = new CFX_PtrArray;
+ m_pData->SetSize(16);
+}
+CFX_BaseMassArrayImp::~CFX_BaseMassArrayImp() {
+ RemoveAll();
+ delete m_pData;
+}
+uint8_t* CFX_BaseMassArrayImp::AddSpaceTo(int32_t index) {
+ FXSYS_assert(index > -1);
+ uint8_t* pChunk;
+ if (index < m_iBlockCount) {
+ pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
+ } else {
+ int32_t iMemSize = m_iChunkSize * m_iBlockSize;
+ while (TRUE) {
+ if (index < m_iChunkCount * m_iChunkSize) {
+ pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
+ break;
+ } else {
+ pChunk = FX_Alloc(uint8_t, iMemSize);
+ if (m_iChunkCount < m_pData->GetSize()) {
+ m_pData->SetAt(m_iChunkCount, pChunk);
+ } else {
+ m_pData->Add(pChunk);
+ }
+ m_iChunkCount++;
+ }
+ }
+ }
+ FXSYS_assert(pChunk != NULL);
+ m_iBlockCount = index + 1;
+ return pChunk + (index % m_iChunkSize) * m_iBlockSize;
+}
+uint8_t* CFX_BaseMassArrayImp::GetAt(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_iBlockCount);
+ uint8_t* pChunk = (uint8_t*)m_pData->GetAt(index / m_iChunkSize);
+ FXSYS_assert(pChunk != NULL);
+ return pChunk + (index % m_iChunkSize) * m_iBlockSize;
+}
+int32_t CFX_BaseMassArrayImp::Append(const CFX_BaseMassArrayImp& src,
+ int32_t iStart,
+ int32_t iCount) {
+ FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
+ int32_t iAdded = src.m_iBlockCount;
+ FXSYS_assert(iStart > -1 && iStart < iAdded);
+ if (iCount < 0) {
+ iCount = iAdded;
+ }
+ if (iStart + iCount > iAdded) {
+ iCount = iAdded - iStart;
+ }
+ if (iCount < 1) {
+ return m_iBlockCount;
+ }
+ int32_t iBlockCount = m_iBlockCount;
+ int32_t iTotal = m_iBlockCount + iCount;
+ AddSpaceTo(iTotal - 1);
+ Append(iBlockCount, src, iStart, iCount);
+ return m_iBlockCount;
+}
+int32_t CFX_BaseMassArrayImp::Copy(const CFX_BaseMassArrayImp& src,
+ int32_t iStart,
+ int32_t iCount) {
+ FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
+ int32_t iCopied = src.m_iBlockCount;
+ FXSYS_assert(iStart > -1);
+ if (iStart >= iCopied) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ if (iCount < 0) {
+ iCount = iCopied;
+ }
+ if (iStart + iCount > iCopied) {
+ iCount = iCopied - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ if (m_iBlockCount < iCount) {
+ AddSpaceTo(iCount - 1);
+ }
+ Append(0, src, iStart, iCount);
+ return m_iBlockCount;
+}
+void CFX_BaseMassArrayImp::Append(int32_t iDstStart,
+ const CFX_BaseMassArrayImp& src,
+ int32_t iSrcStart,
+ int32_t iSrcCount) {
+ FXSYS_assert(iDstStart > -1 && m_iBlockSize == src.m_iBlockSize);
+ int32_t iSrcTotal = src.m_iBlockCount;
+ FXSYS_assert(iSrcTotal > 0 && m_iBlockCount >= iDstStart + iSrcCount);
+ FXSYS_assert(iSrcStart > -1 && iSrcStart < iSrcTotal && iSrcCount > 0 &&
+ iSrcStart + iSrcCount <= iSrcTotal);
+ int32_t iDstChunkIndex = iDstStart / m_iChunkSize;
+ int32_t iSrcChunkIndex = iSrcStart / src.m_iChunkSize;
+ uint8_t* pDstChunk = (uint8_t*)GetAt(iDstStart);
+ uint8_t* pSrcChunk = (uint8_t*)src.GetAt(iSrcStart);
+ int32_t iDstChunkSize = m_iChunkSize - (iDstStart % m_iChunkSize);
+ int32_t iSrcChunkSize = src.m_iChunkSize - (iSrcStart % src.m_iChunkSize);
+ int32_t iCopySize =
+ std::min(iSrcCount, std::min(iSrcChunkSize, iDstChunkSize));
+ int32_t iCopyBytes = iCopySize * m_iBlockSize;
+ while (iSrcCount > 0) {
+ FXSYS_assert(pDstChunk != NULL && pSrcChunk != NULL);
+ FXSYS_memcpy(pDstChunk, pSrcChunk, iCopyBytes);
+ iSrcCount -= iCopySize;
+ iSrcChunkSize -= iCopySize;
+ if (iSrcChunkSize < 1) {
+ iSrcChunkSize = src.m_iChunkSize;
+ iSrcChunkIndex++;
+ pSrcChunk = (uint8_t*)src.m_pData->GetAt(iSrcChunkIndex);
+ } else {
+ pSrcChunk += iCopyBytes;
+ }
+ iDstChunkSize -= iCopySize;
+ if (iDstChunkSize < 1) {
+ iDstChunkSize = m_iChunkSize;
+ iDstChunkIndex++;
+ pDstChunk = (uint8_t*)m_pData->GetAt(iDstChunkIndex);
+ } else {
+ pDstChunk += iCopyBytes;
+ }
+ iCopySize = std::min(iSrcCount, std::min(iSrcChunkSize, iDstChunkSize));
+ iCopyBytes = iCopySize * m_iBlockSize;
+ }
+}
+int32_t CFX_BaseMassArrayImp::RemoveLast(int32_t iCount) {
+ if (iCount < 0 || iCount >= m_iBlockCount) {
+ m_iBlockCount = 0;
+ } else {
+ m_iBlockCount -= iCount;
+ }
+ return m_iBlockCount;
+}
+void CFX_BaseMassArrayImp::RemoveAll(FX_BOOL bLeaveMemory) {
+ if (bLeaveMemory) {
+ m_iBlockCount = 0;
+ return;
+ }
+ for (int32_t i = 0; i < m_iChunkCount; i++) {
+ void* p = m_pData->GetAt(i);
+ if (p == NULL) {
+ continue;
+ }
+ FX_Free(p);
+ }
+ m_pData->RemoveAll();
+ m_iChunkCount = 0;
+ m_iBlockCount = 0;
+}
+CFX_BaseMassArray::CFX_BaseMassArray(int32_t iChunkSize, int32_t iBlockSize) {
+ m_pData = new CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
+}
+CFX_BaseMassArray::~CFX_BaseMassArray() {
+ delete m_pData;
+}
+int32_t CFX_BaseMassArray::GetSize() const {
+ return m_pData->m_iBlockCount;
+}
+uint8_t* CFX_BaseMassArray::AddSpaceTo(int32_t index) {
+ return m_pData->AddSpaceTo(index);
+}
+uint8_t* CFX_BaseMassArray::GetAt(int32_t index) const {
+ return m_pData->GetAt(index);
+}
+int32_t CFX_BaseMassArray::Append(const CFX_BaseMassArray& src,
+ int32_t iStart,
+ int32_t iCount) {
+ return m_pData->Append(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
+}
+int32_t CFX_BaseMassArray::Copy(const CFX_BaseMassArray& src,
+ int32_t iStart,
+ int32_t iCount) {
+ return m_pData->Copy(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
+}
+int32_t CFX_BaseMassArray::RemoveLast(int32_t iCount) {
+ return m_pData->RemoveLast(iCount);
+}
+void CFX_BaseMassArray::RemoveAll(FX_BOOL bLeaveMemory) {
+ m_pData->RemoveAll(bLeaveMemory);
+}
+typedef struct _FX_BASEDISCRETEARRAYDATA {
+ int32_t iBlockSize;
+ int32_t iChunkSize;
+ int32_t iChunkCount;
+ CFX_PtrArray ChunkBuffer;
+} FX_BASEDISCRETEARRAYDATA, *FX_LPBASEDISCRETEARRAYDATA;
+typedef FX_BASEDISCRETEARRAYDATA const* FX_LPCBASEDISCRETEARRAYDATA;
+CFX_BaseDiscreteArray::CFX_BaseDiscreteArray(int32_t iChunkSize,
+ int32_t iBlockSize) {
+ FXSYS_assert(iChunkSize > 0 && iBlockSize > 0);
+ FX_LPBASEDISCRETEARRAYDATA pData;
+ m_pData = pData = new FX_BASEDISCRETEARRAYDATA;
+ pData->ChunkBuffer.SetSize(16);
+ pData->iChunkCount = 0;
+ pData->iChunkSize = iChunkSize;
+ pData->iBlockSize = iBlockSize;
+}
+CFX_BaseDiscreteArray::~CFX_BaseDiscreteArray() {
+ RemoveAll();
+ delete (FX_LPBASEDISCRETEARRAYDATA) m_pData;
+}
+uint8_t* CFX_BaseDiscreteArray::AddSpaceTo(int32_t index) {
+ FXSYS_assert(index > -1);
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ int32_t& iChunkCount = pData->iChunkCount;
+ int32_t iChunkSize = pData->iChunkSize;
+ uint8_t* pChunk = NULL;
+ int32_t iChunk = index / iChunkSize;
+ if (iChunk < iChunkCount) {
+ pChunk = (uint8_t*)pData->ChunkBuffer.GetAt(iChunk);
+ }
+ if (!pChunk) {
+ pChunk = FX_Alloc2D(uint8_t, iChunkSize, pData->iBlockSize);
+ FXSYS_memset(pChunk, 0, iChunkSize * pData->iBlockSize);
+ pData->ChunkBuffer.SetAtGrow(iChunk, pChunk);
+ if (iChunkCount <= iChunk) {
+ iChunkCount = iChunk + 1;
+ }
+ }
+ return pChunk + (index % iChunkSize) * pData->iBlockSize;
+}
+uint8_t* CFX_BaseDiscreteArray::GetAt(int32_t index) const {
+ FXSYS_assert(index > -1);
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ int32_t iChunkSize = pData->iChunkSize;
+ int32_t iChunk = index / iChunkSize;
+ if (iChunk >= pData->iChunkCount) {
+ return NULL;
+ }
+ uint8_t* pChunk = (uint8_t*)pData->ChunkBuffer.GetAt(iChunk);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ return pChunk + (index % iChunkSize) * pData->iBlockSize;
+}
+void CFX_BaseDiscreteArray::RemoveAll() {
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ CFX_PtrArray& ChunkBuffer = pData->ChunkBuffer;
+ int32_t& iChunkCount = pData->iChunkCount;
+ for (int32_t i = 0; i < iChunkCount; i++) {
+ void* p = ChunkBuffer.GetAt(i);
+ if (p == NULL) {
+ continue;
+ }
+ FX_Free(p);
+ }
+ ChunkBuffer.RemoveAll();
+ iChunkCount = 0;
+}
+CFX_BaseStack::CFX_BaseStack(int32_t iChunkSize, int32_t iBlockSize) {
+ m_pData = new CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
+}
+CFX_BaseStack::~CFX_BaseStack() {
+ delete (CFX_BaseMassArrayImp*)m_pData;
+}
+uint8_t* CFX_BaseStack::Push() {
+ return m_pData->AddSpace();
+}
+void CFX_BaseStack::Pop() {
+ int32_t& iBlockCount = m_pData->m_iBlockCount;
+ if (iBlockCount < 1) {
+ return;
+ }
+ iBlockCount--;
+}
+uint8_t* CFX_BaseStack::GetTopElement() const {
+ int32_t iSize = m_pData->m_iBlockCount;
+ if (iSize < 1) {
+ return NULL;
+ }
+ return m_pData->GetAt(iSize - 1);
+}
+int32_t CFX_BaseStack::GetSize() const {
+ return m_pData->m_iBlockCount;
+}
+uint8_t* CFX_BaseStack::GetAt(int32_t index) const {
+ return m_pData->GetAt(index);
+}
+void CFX_BaseStack::RemoveAll(FX_BOOL bLeaveMemory) {
+ m_pData->RemoveAll(bLeaveMemory);
+}
diff --git a/xfa/src/fgas/src/crt/fx_utils.h b/xfa/src/fgas/src/crt/fx_utils.h
index abee43df72..35fdd54423 100644
--- a/xfa/src/fgas/src/crt/fx_utils.h
+++ b/xfa/src/fgas/src/crt/fx_utils.h
@@ -1,36 +1,36 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_UTILS_IMP
-#define _FX_UTILS_IMP
-class CFX_BaseMassArrayImp : public CFX_Target {
- public:
- CFX_BaseMassArrayImp(int32_t iChunkSize, int32_t iBlockSize);
- ~CFX_BaseMassArrayImp();
- uint8_t* AddSpace() { return AddSpaceTo(m_iBlockCount); }
- uint8_t* AddSpaceTo(int32_t index);
- uint8_t* GetAt(int32_t index) const;
- int32_t Append(const CFX_BaseMassArrayImp& src,
- int32_t iStart = 0,
- int32_t iCount = -1);
- int32_t Copy(const CFX_BaseMassArrayImp& src,
- int32_t iStart = 0,
- int32_t iCount = -1);
- int32_t RemoveLast(int32_t iCount = -1);
- void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
- int32_t m_iChunkSize;
- int32_t m_iBlockSize;
- int32_t m_iChunkCount;
- int32_t m_iBlockCount;
- CFX_PtrArray* m_pData;
-
- protected:
- void Append(int32_t iDstStart,
- const CFX_BaseMassArrayImp& src,
- int32_t iSrcStart = 0,
- int32_t iSrcCount = -1);
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_UTILS_IMP
+#define _FX_UTILS_IMP
+class CFX_BaseMassArrayImp : public CFX_Target {
+ public:
+ CFX_BaseMassArrayImp(int32_t iChunkSize, int32_t iBlockSize);
+ ~CFX_BaseMassArrayImp();
+ uint8_t* AddSpace() { return AddSpaceTo(m_iBlockCount); }
+ uint8_t* AddSpaceTo(int32_t index);
+ uint8_t* GetAt(int32_t index) const;
+ int32_t Append(const CFX_BaseMassArrayImp& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t Copy(const CFX_BaseMassArrayImp& src,
+ int32_t iStart = 0,
+ int32_t iCount = -1);
+ int32_t RemoveLast(int32_t iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ int32_t m_iChunkSize;
+ int32_t m_iBlockSize;
+ int32_t m_iChunkCount;
+ int32_t m_iBlockCount;
+ CFX_PtrArray* m_pData;
+
+ protected:
+ void Append(int32_t iDstStart,
+ const CFX_BaseMassArrayImp& src,
+ int32_t iSrcStart = 0,
+ int32_t iSrcCount = -1);
+};
+#endif
diff --git a/xfa/src/fgas/src/fgas_base.h b/xfa/src/fgas/src/fgas_base.h
index eea3b6cac4..df5e56a192 100644
--- a/xfa/src/fgas/src/fgas_base.h
+++ b/xfa/src/fgas/src/fgas_base.h
@@ -1,14 +1,14 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-// TODO(thestig): Remove this file and do IWYU.
-
-#ifndef _FXMATH_BASE_
-#define _FXMATH_BASE_
-#include "xfa/src/foxitlib.h"
-#include "core/include/fxge/fx_freetype.h"
-#include "xfa/src/fgas/include/fgas.h"
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+// TODO(thestig): Remove this file and do IWYU.
+
+#ifndef _FXMATH_BASE_
+#define _FXMATH_BASE_
+#include "xfa/src/foxitlib.h"
+#include "core/include/fxge/fx_freetype.h"
+#include "xfa/src/fgas/include/fgas.h"
+#endif
diff --git a/xfa/src/fgas/src/font/fx_fontutils.cpp b/xfa/src/fgas/src/font/fx_fontutils.cpp
index a57e059f72..9372f6a572 100644
--- a/xfa/src/fgas/src/font/fx_fontutils.cpp
+++ b/xfa/src/fgas/src/font/fx_fontutils.cpp
@@ -1,149 +1,149 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_fontutils.h"
-FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles) {
- FX_DWORD dwHash = wCodePage;
- if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
- dwHash |= 0x00010000;
- }
- if (dwFontStyles & FX_FONTSTYLE_Serif) {
- dwHash |= 0x00020000;
- }
- if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
- dwHash |= 0x00040000;
- }
- if (dwFontStyles & FX_FONTSTYLE_Script) {
- dwHash |= 0x00080000;
- }
- if (dwFontStyles & FX_FONTSTYLE_Italic) {
- dwHash |= 0x00100000;
- }
- if (dwFontStyles & FX_FONTSTYLE_Bold) {
- dwHash |= 0x00200000;
- }
- return dwHash;
-}
-FX_DWORD FGAS_GetFontFamilyHash(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage) {
- CFX_WideString wsFont(pszFontFamily);
- if (dwFontStyles & FX_FONTSTYLE_Bold) {
- wsFont += L"Bold";
- }
- if (dwFontStyles & FX_FONTSTYLE_Italic) {
- wsFont += L"Italic";
- }
- wsFont += wCodePage;
- return FX_HashCode_String_GetW((const FX_WCHAR*)wsFont, wsFont.GetLength());
-}
-static const FGAS_FONTUSB g_FXGdiFontUSBTable[] = {
- {0x0000, 0x007F, 0, 1252}, {0x0080, 0x00FF, 1, 1252},
- {0x0100, 0x017F, 2, 1250}, {0x0180, 0x024F, 3, 1250},
- {0x0250, 0x02AF, 4, 0xFFFF}, {0x02B0, 0x02FF, 5, 0xFFFF},
- {0x0300, 0x036F, 6, 0xFFFF}, {0x0370, 0x03FF, 7, 1253},
- {0x0400, 0x04FF, 9, 1251}, {0x0500, 0x052F, 9, 0xFFFF},
- {0x0530, 0x058F, 10, 0xFFFF}, {0x0590, 0x05FF, 11, 1255},
- {0x0600, 0x06FF, 13, 1256}, {0x0700, 0x074F, 71, 0xFFFF},
- {0x0750, 0x077F, 13, 0xFFFF}, {0x0780, 0x07BF, 72, 0xFFFF},
- {0x07C0, 0x07FF, 14, 0xFFFF}, {0x0800, 0x08FF, 999, 0xFFFF},
- {0x0900, 0x097F, 15, 0xFFFF}, {0x0980, 0x09FF, 16, 0xFFFF},
- {0x0A00, 0x0A7F, 17, 0xFFFF}, {0x0A80, 0x0AFF, 18, 0xFFFF},
- {0x0B00, 0x0B7F, 19, 0xFFFF}, {0x0B80, 0x0BFF, 20, 0xFFFF},
- {0x0C00, 0x0C7F, 21, 0xFFFF}, {0x0C80, 0x0CFF, 22, 0xFFFF},
- {0x0D00, 0x0D7F, 23, 0xFFFF}, {0x0D80, 0x0DFF, 73, 0xFFFF},
- {0x0E00, 0x0E7F, 24, 874}, {0x0E80, 0x0EFF, 25, 0xFFFF},
- {0x0F00, 0x0FFF, 70, 0xFFFF}, {0x1000, 0x109F, 74, 0xFFFF},
- {0x10A0, 0x10FF, 26, 0xFFFF}, {0x1100, 0x11FF, 28, 0xFFFF},
- {0x1200, 0x137F, 75, 0xFFFF}, {0x1380, 0x139F, 75, 0xFFFF},
- {0x13A0, 0x13FF, 76, 0xFFFF}, {0x1400, 0x167F, 77, 0xFFFF},
- {0x1680, 0x169F, 78, 0xFFFF}, {0x16A0, 0x16FF, 79, 0xFFFF},
- {0x1700, 0x171F, 84, 0xFFFF}, {0x1720, 0x173F, 84, 0xFFFF},
- {0x1740, 0x175F, 84, 0xFFFF}, {0x1760, 0x177F, 84, 0xFFFF},
- {0x1780, 0x17FF, 80, 0xFFFF}, {0x1800, 0x18AF, 81, 0xFFFF},
- {0x18B0, 0x18FF, 999, 0xFFFF}, {0x1900, 0x194F, 93, 0xFFFF},
- {0x1950, 0x197F, 94, 0xFFFF}, {0x1980, 0x19DF, 95, 0xFFFF},
- {0x19E0, 0x19FF, 80, 0xFFFF}, {0x1A00, 0x1A1F, 96, 0xFFFF},
- {0x1A20, 0x1AFF, 999, 0xFFFF}, {0x1B00, 0x1B7F, 27, 0xFFFF},
- {0x1B80, 0x1BBF, 112, 0xFFFF}, {0x1BC0, 0x1BFF, 999, 0xFFFF},
- {0x1C00, 0x1C4F, 113, 0xFFFF}, {0x1C50, 0x1C7F, 114, 0xFFFF},
- {0x1C80, 0x1CFF, 999, 0xFFFF}, {0x1D00, 0x1D7F, 4, 0xFFFF},
- {0x1D80, 0x1DBF, 4, 0xFFFF}, {0x1DC0, 0x1DFF, 6, 0xFFFF},
- {0x1E00, 0x1EFF, 29, 0xFFFF}, {0x1F00, 0x1FFF, 30, 0xFFFF},
- {0x2000, 0x206F, 31, 0xFFFF}, {0x2070, 0x209F, 32, 0xFFFF},
- {0x20A0, 0x20CF, 33, 0xFFFF}, {0x20D0, 0x20FF, 34, 0xFFFF},
- {0x2100, 0x214F, 35, 0xFFFF}, {0x2150, 0x215F, 36, 0xFFFF},
- {0x2160, 0x216B, 36, 936}, {0x216C, 0x216F, 36, 0xFFFF},
- {0x2170, 0x2179, 36, 936}, {0x217A, 0x218F, 36, 0xFFFF},
- {0x2190, 0x2199, 37, 949}, {0x219A, 0x21FF, 37, 0xFFFF},
- {0x2200, 0x22FF, 38, 0xFFFF}, {0x2300, 0x23FF, 39, 0xFFFF},
- {0x2400, 0x243F, 40, 0xFFFF}, {0x2440, 0x245F, 41, 0xFFFF},
- {0x2460, 0x2473, 42, 932}, {0x2474, 0x249B, 42, 936},
- {0x249C, 0x24E9, 42, 949}, {0x24EA, 0x24FF, 42, 0xFFFF},
- {0x2500, 0x2573, 43, 936}, {0x2574, 0x257F, 43, 0xFFFF},
- {0x2580, 0x2580, 44, 0xFFFF}, {0x2581, 0x258F, 44, 936},
- {0x2590, 0x259F, 44, 0xFFFF}, {0x25A0, 0x25FF, 45, 0xFFFF},
- {0x2600, 0x26FF, 46, 0xFFFF}, {0x2700, 0x27BF, 47, 0xFFFF},
- {0x27C0, 0x27EF, 38, 0xFFFF}, {0x27F0, 0x27FF, 37, 0xFFFF},
- {0x2800, 0x28FF, 82, 0xFFFF}, {0x2900, 0x297F, 37, 0xFFFF},
- {0x2980, 0x29FF, 38, 0xFFFF}, {0x2A00, 0x2AFF, 38, 0xFFFF},
- {0x2B00, 0x2BFF, 37, 0xFFFF}, {0x2C00, 0x2C5F, 97, 0xFFFF},
- {0x2C60, 0x2C7F, 29, 0xFFFF}, {0x2C80, 0x2CFF, 8, 0xFFFF},
- {0x2D00, 0x2D2F, 26, 0xFFFF}, {0x2D30, 0x2D7F, 98, 0xFFFF},
- {0x2D80, 0x2DDF, 75, 0xFFFF}, {0x2DE0, 0x2DFF, 9, 0xFFFF},
- {0x2E00, 0x2E7F, 31, 0xFFFF}, {0x2E80, 0x2EFF, 59, 0xFFFF},
- {0x2F00, 0x2FDF, 59, 0xFFFF}, {0x2FE0, 0x2FEF, 999, 0xFFFF},
- {0x2FF0, 0x2FFF, 59, 0xFFFF}, {0x3000, 0x303F, 48, 0xFFFF},
- {0x3040, 0x309F, 49, 932}, {0x30A0, 0x30FF, 50, 932},
- {0x3100, 0x3129, 51, 936}, {0x312A, 0x312F, 51, 0xFFFF},
- {0x3130, 0x318F, 52, 949}, {0x3190, 0x319F, 59, 0xFFFF},
- {0x31A0, 0x31BF, 51, 0xFFFF}, {0x31C0, 0x31EF, 61, 0xFFFF},
- {0x31F0, 0x31FF, 50, 0xFFFF}, {0x3200, 0x321C, 54, 949},
- {0x321D, 0x325F, 54, 0xFFFF}, {0x3260, 0x327F, 54, 949},
- {0x3280, 0x32FF, 54, 0xFFFF}, {0x3300, 0x3387, 55, 0xFFFF},
- {0x3388, 0x33D0, 55, 949}, {0x33D1, 0x33FF, 55, 0xFFFF},
- {0x3400, 0x4DBF, 59, 0xFFFF}, {0x4DC0, 0x4DFF, 99, 0xFFFF},
- {0x4E00, 0x9FA5, 59, 936}, {0x9FA6, 0x9FFF, 59, 0xFFFF},
- {0xA000, 0xA48F, 83, 0xFFFF}, {0xA490, 0xA4CF, 83, 0xFFFF},
- {0xA4D0, 0xA4FF, 999, 0xFFFF}, {0xA500, 0xA63F, 12, 0xFFFF},
- {0xA640, 0xA69F, 9, 0xFFFF}, {0xA6A0, 0xA6FF, 999, 0xFFFF},
- {0xA700, 0xA71F, 5, 0xFFFF}, {0xA720, 0xA7FF, 29, 0xFFFF},
- {0xA800, 0xA82F, 100, 0xFFFF}, {0xA830, 0xA8FF, 999, 0xFFFF},
- {0xA840, 0xA87F, 53, 0xFFFF}, {0xA880, 0xA8DF, 115, 0xFFFF},
- {0xA8E0, 0xA8FF, 999, 0xFFFF}, {0xA900, 0xA92F, 116, 0xFFFF},
- {0xA930, 0xA95F, 117, 0xFFFF}, {0xA960, 0xA9FF, 999, 0xFFFF},
- {0xAA00, 0xAA5F, 118, 0xFFFF}, {0xAA60, 0xABFF, 999, 0xFFFF},
- {0xAC00, 0xD7AF, 56, 949}, {0xD7B0, 0xD7FF, 999, 0xFFFF},
- {0xD800, 0xDB7F, 57, 0xFFFF}, {0xDB80, 0xDBFF, 57, 0xFFFF},
- {0xDC00, 0xDFFF, 57, 0xFFFF}, {0xE000, 0xE814, 60, 0xFFFF},
- {0xE815, 0xE864, 60, 936}, {0xE865, 0xF8FF, 60, 0xFFFF},
- {0xF900, 0xFA0B, 61, 949}, {0xFA0C, 0xFA0D, 61, 936},
- {0xFA0E, 0xFA2D, 61, 932}, {0xFA2E, 0xFAFF, 61, 0xFFFF},
- {0xFB00, 0xFB4F, 62, 0xFFFF}, {0xFB50, 0xFDFF, 63, 1256},
- {0xFE00, 0xFE0F, 91, 0xFFFF}, {0xFE10, 0xFE1F, 65, 0xFFFF},
- {0xFE20, 0xFE2F, 64, 0xFFFF}, {0xFE30, 0xFE4F, 65, 0xFFFF},
- {0xFE50, 0xFE6F, 66, 0xFFFF}, {0xFE70, 0xFEFF, 67, 1256},
- {0xFF00, 0xFF5F, 68, 936}, {0xFF60, 0xFF9F, 68, 932},
- {0xFFA0, 0xFFEF, 68, 0xFFFF},
-};
-FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode) {
- int32_t iEnd = sizeof(g_FXGdiFontUSBTable) / sizeof(FGAS_FONTUSB) - 1;
- FXSYS_assert(iEnd >= 0);
- int32_t iStart = 0, iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const FGAS_FONTUSB& usb = g_FXGdiFontUSBTable[iMid];
- if (wUnicode < usb.wStartUnicode) {
- iEnd = iMid - 1;
- } else if (wUnicode > usb.wEndUnicode) {
- iStart = iMid + 1;
- } else {
- return &usb;
- }
- } while (iStart <= iEnd);
- return NULL;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_fontutils.h"
+FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles) {
+ FX_DWORD dwHash = wCodePage;
+ if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
+ dwHash |= 0x00010000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ dwHash |= 0x00020000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ dwHash |= 0x00040000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ dwHash |= 0x00080000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ dwHash |= 0x00100000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ dwHash |= 0x00200000;
+ }
+ return dwHash;
+}
+FX_DWORD FGAS_GetFontFamilyHash(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage) {
+ CFX_WideString wsFont(pszFontFamily);
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ wsFont += L"Bold";
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ wsFont += L"Italic";
+ }
+ wsFont += wCodePage;
+ return FX_HashCode_String_GetW((const FX_WCHAR*)wsFont, wsFont.GetLength());
+}
+static const FGAS_FONTUSB g_FXGdiFontUSBTable[] = {
+ {0x0000, 0x007F, 0, 1252}, {0x0080, 0x00FF, 1, 1252},
+ {0x0100, 0x017F, 2, 1250}, {0x0180, 0x024F, 3, 1250},
+ {0x0250, 0x02AF, 4, 0xFFFF}, {0x02B0, 0x02FF, 5, 0xFFFF},
+ {0x0300, 0x036F, 6, 0xFFFF}, {0x0370, 0x03FF, 7, 1253},
+ {0x0400, 0x04FF, 9, 1251}, {0x0500, 0x052F, 9, 0xFFFF},
+ {0x0530, 0x058F, 10, 0xFFFF}, {0x0590, 0x05FF, 11, 1255},
+ {0x0600, 0x06FF, 13, 1256}, {0x0700, 0x074F, 71, 0xFFFF},
+ {0x0750, 0x077F, 13, 0xFFFF}, {0x0780, 0x07BF, 72, 0xFFFF},
+ {0x07C0, 0x07FF, 14, 0xFFFF}, {0x0800, 0x08FF, 999, 0xFFFF},
+ {0x0900, 0x097F, 15, 0xFFFF}, {0x0980, 0x09FF, 16, 0xFFFF},
+ {0x0A00, 0x0A7F, 17, 0xFFFF}, {0x0A80, 0x0AFF, 18, 0xFFFF},
+ {0x0B00, 0x0B7F, 19, 0xFFFF}, {0x0B80, 0x0BFF, 20, 0xFFFF},
+ {0x0C00, 0x0C7F, 21, 0xFFFF}, {0x0C80, 0x0CFF, 22, 0xFFFF},
+ {0x0D00, 0x0D7F, 23, 0xFFFF}, {0x0D80, 0x0DFF, 73, 0xFFFF},
+ {0x0E00, 0x0E7F, 24, 874}, {0x0E80, 0x0EFF, 25, 0xFFFF},
+ {0x0F00, 0x0FFF, 70, 0xFFFF}, {0x1000, 0x109F, 74, 0xFFFF},
+ {0x10A0, 0x10FF, 26, 0xFFFF}, {0x1100, 0x11FF, 28, 0xFFFF},
+ {0x1200, 0x137F, 75, 0xFFFF}, {0x1380, 0x139F, 75, 0xFFFF},
+ {0x13A0, 0x13FF, 76, 0xFFFF}, {0x1400, 0x167F, 77, 0xFFFF},
+ {0x1680, 0x169F, 78, 0xFFFF}, {0x16A0, 0x16FF, 79, 0xFFFF},
+ {0x1700, 0x171F, 84, 0xFFFF}, {0x1720, 0x173F, 84, 0xFFFF},
+ {0x1740, 0x175F, 84, 0xFFFF}, {0x1760, 0x177F, 84, 0xFFFF},
+ {0x1780, 0x17FF, 80, 0xFFFF}, {0x1800, 0x18AF, 81, 0xFFFF},
+ {0x18B0, 0x18FF, 999, 0xFFFF}, {0x1900, 0x194F, 93, 0xFFFF},
+ {0x1950, 0x197F, 94, 0xFFFF}, {0x1980, 0x19DF, 95, 0xFFFF},
+ {0x19E0, 0x19FF, 80, 0xFFFF}, {0x1A00, 0x1A1F, 96, 0xFFFF},
+ {0x1A20, 0x1AFF, 999, 0xFFFF}, {0x1B00, 0x1B7F, 27, 0xFFFF},
+ {0x1B80, 0x1BBF, 112, 0xFFFF}, {0x1BC0, 0x1BFF, 999, 0xFFFF},
+ {0x1C00, 0x1C4F, 113, 0xFFFF}, {0x1C50, 0x1C7F, 114, 0xFFFF},
+ {0x1C80, 0x1CFF, 999, 0xFFFF}, {0x1D00, 0x1D7F, 4, 0xFFFF},
+ {0x1D80, 0x1DBF, 4, 0xFFFF}, {0x1DC0, 0x1DFF, 6, 0xFFFF},
+ {0x1E00, 0x1EFF, 29, 0xFFFF}, {0x1F00, 0x1FFF, 30, 0xFFFF},
+ {0x2000, 0x206F, 31, 0xFFFF}, {0x2070, 0x209F, 32, 0xFFFF},
+ {0x20A0, 0x20CF, 33, 0xFFFF}, {0x20D0, 0x20FF, 34, 0xFFFF},
+ {0x2100, 0x214F, 35, 0xFFFF}, {0x2150, 0x215F, 36, 0xFFFF},
+ {0x2160, 0x216B, 36, 936}, {0x216C, 0x216F, 36, 0xFFFF},
+ {0x2170, 0x2179, 36, 936}, {0x217A, 0x218F, 36, 0xFFFF},
+ {0x2190, 0x2199, 37, 949}, {0x219A, 0x21FF, 37, 0xFFFF},
+ {0x2200, 0x22FF, 38, 0xFFFF}, {0x2300, 0x23FF, 39, 0xFFFF},
+ {0x2400, 0x243F, 40, 0xFFFF}, {0x2440, 0x245F, 41, 0xFFFF},
+ {0x2460, 0x2473, 42, 932}, {0x2474, 0x249B, 42, 936},
+ {0x249C, 0x24E9, 42, 949}, {0x24EA, 0x24FF, 42, 0xFFFF},
+ {0x2500, 0x2573, 43, 936}, {0x2574, 0x257F, 43, 0xFFFF},
+ {0x2580, 0x2580, 44, 0xFFFF}, {0x2581, 0x258F, 44, 936},
+ {0x2590, 0x259F, 44, 0xFFFF}, {0x25A0, 0x25FF, 45, 0xFFFF},
+ {0x2600, 0x26FF, 46, 0xFFFF}, {0x2700, 0x27BF, 47, 0xFFFF},
+ {0x27C0, 0x27EF, 38, 0xFFFF}, {0x27F0, 0x27FF, 37, 0xFFFF},
+ {0x2800, 0x28FF, 82, 0xFFFF}, {0x2900, 0x297F, 37, 0xFFFF},
+ {0x2980, 0x29FF, 38, 0xFFFF}, {0x2A00, 0x2AFF, 38, 0xFFFF},
+ {0x2B00, 0x2BFF, 37, 0xFFFF}, {0x2C00, 0x2C5F, 97, 0xFFFF},
+ {0x2C60, 0x2C7F, 29, 0xFFFF}, {0x2C80, 0x2CFF, 8, 0xFFFF},
+ {0x2D00, 0x2D2F, 26, 0xFFFF}, {0x2D30, 0x2D7F, 98, 0xFFFF},
+ {0x2D80, 0x2DDF, 75, 0xFFFF}, {0x2DE0, 0x2DFF, 9, 0xFFFF},
+ {0x2E00, 0x2E7F, 31, 0xFFFF}, {0x2E80, 0x2EFF, 59, 0xFFFF},
+ {0x2F00, 0x2FDF, 59, 0xFFFF}, {0x2FE0, 0x2FEF, 999, 0xFFFF},
+ {0x2FF0, 0x2FFF, 59, 0xFFFF}, {0x3000, 0x303F, 48, 0xFFFF},
+ {0x3040, 0x309F, 49, 932}, {0x30A0, 0x30FF, 50, 932},
+ {0x3100, 0x3129, 51, 936}, {0x312A, 0x312F, 51, 0xFFFF},
+ {0x3130, 0x318F, 52, 949}, {0x3190, 0x319F, 59, 0xFFFF},
+ {0x31A0, 0x31BF, 51, 0xFFFF}, {0x31C0, 0x31EF, 61, 0xFFFF},
+ {0x31F0, 0x31FF, 50, 0xFFFF}, {0x3200, 0x321C, 54, 949},
+ {0x321D, 0x325F, 54, 0xFFFF}, {0x3260, 0x327F, 54, 949},
+ {0x3280, 0x32FF, 54, 0xFFFF}, {0x3300, 0x3387, 55, 0xFFFF},
+ {0x3388, 0x33D0, 55, 949}, {0x33D1, 0x33FF, 55, 0xFFFF},
+ {0x3400, 0x4DBF, 59, 0xFFFF}, {0x4DC0, 0x4DFF, 99, 0xFFFF},
+ {0x4E00, 0x9FA5, 59, 936}, {0x9FA6, 0x9FFF, 59, 0xFFFF},
+ {0xA000, 0xA48F, 83, 0xFFFF}, {0xA490, 0xA4CF, 83, 0xFFFF},
+ {0xA4D0, 0xA4FF, 999, 0xFFFF}, {0xA500, 0xA63F, 12, 0xFFFF},
+ {0xA640, 0xA69F, 9, 0xFFFF}, {0xA6A0, 0xA6FF, 999, 0xFFFF},
+ {0xA700, 0xA71F, 5, 0xFFFF}, {0xA720, 0xA7FF, 29, 0xFFFF},
+ {0xA800, 0xA82F, 100, 0xFFFF}, {0xA830, 0xA8FF, 999, 0xFFFF},
+ {0xA840, 0xA87F, 53, 0xFFFF}, {0xA880, 0xA8DF, 115, 0xFFFF},
+ {0xA8E0, 0xA8FF, 999, 0xFFFF}, {0xA900, 0xA92F, 116, 0xFFFF},
+ {0xA930, 0xA95F, 117, 0xFFFF}, {0xA960, 0xA9FF, 999, 0xFFFF},
+ {0xAA00, 0xAA5F, 118, 0xFFFF}, {0xAA60, 0xABFF, 999, 0xFFFF},
+ {0xAC00, 0xD7AF, 56, 949}, {0xD7B0, 0xD7FF, 999, 0xFFFF},
+ {0xD800, 0xDB7F, 57, 0xFFFF}, {0xDB80, 0xDBFF, 57, 0xFFFF},
+ {0xDC00, 0xDFFF, 57, 0xFFFF}, {0xE000, 0xE814, 60, 0xFFFF},
+ {0xE815, 0xE864, 60, 936}, {0xE865, 0xF8FF, 60, 0xFFFF},
+ {0xF900, 0xFA0B, 61, 949}, {0xFA0C, 0xFA0D, 61, 936},
+ {0xFA0E, 0xFA2D, 61, 932}, {0xFA2E, 0xFAFF, 61, 0xFFFF},
+ {0xFB00, 0xFB4F, 62, 0xFFFF}, {0xFB50, 0xFDFF, 63, 1256},
+ {0xFE00, 0xFE0F, 91, 0xFFFF}, {0xFE10, 0xFE1F, 65, 0xFFFF},
+ {0xFE20, 0xFE2F, 64, 0xFFFF}, {0xFE30, 0xFE4F, 65, 0xFFFF},
+ {0xFE50, 0xFE6F, 66, 0xFFFF}, {0xFE70, 0xFEFF, 67, 1256},
+ {0xFF00, 0xFF5F, 68, 936}, {0xFF60, 0xFF9F, 68, 932},
+ {0xFFA0, 0xFFEF, 68, 0xFFFF},
+};
+FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode) {
+ int32_t iEnd = sizeof(g_FXGdiFontUSBTable) / sizeof(FGAS_FONTUSB) - 1;
+ FXSYS_assert(iEnd >= 0);
+ int32_t iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FGAS_FONTUSB& usb = g_FXGdiFontUSBTable[iMid];
+ if (wUnicode < usb.wStartUnicode) {
+ iEnd = iMid - 1;
+ } else if (wUnicode > usb.wEndUnicode) {
+ iStart = iMid + 1;
+ } else {
+ return &usb;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
diff --git a/xfa/src/fgas/src/font/fx_fontutils.h b/xfa/src/fgas/src/font/fx_fontutils.h
index 38ff5764d9..0bac043d48 100644
--- a/xfa/src/fgas/src/font/fx_fontutils.h
+++ b/xfa/src/fgas/src/font/fx_fontutils.h
@@ -1,21 +1,21 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FGAS_FONTUTIL_H_
-#define _FGAS_FONTUTIL_H_
-typedef struct _FGAS_FONTUSB {
- FX_WCHAR wStartUnicode;
- FX_WCHAR wEndUnicode;
- FX_WORD wBitField;
- FX_WORD wCodePage;
-} FGAS_FONTUSB, *FGAS_LPFONTUSB;
-typedef FGAS_FONTUSB const* FGAS_LPCFONTUSB;
-FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles);
-FX_DWORD FGAS_GetFontFamilyHash(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage);
-FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode);
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_FONTUTIL_H_
+#define _FGAS_FONTUTIL_H_
+typedef struct _FGAS_FONTUSB {
+ FX_WCHAR wStartUnicode;
+ FX_WCHAR wEndUnicode;
+ FX_WORD wBitField;
+ FX_WORD wCodePage;
+} FGAS_FONTUSB, *FGAS_LPFONTUSB;
+typedef FGAS_FONTUSB const* FGAS_LPCFONTUSB;
+FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles);
+FX_DWORD FGAS_GetFontFamilyHash(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage);
+FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode);
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gdifont.cpp b/xfa/src/fgas/src/font/fx_gdifont.cpp
index aa923b6a21..c14db35709 100644
--- a/xfa/src/fgas/src/font/fx_gdifont.cpp
+++ b/xfa/src/fgas/src/font/fx_gdifont.cpp
@@ -1,539 +1,539 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_gdifont.h"
-#include "fx_stdfontmgr.h"
-#ifdef _FXPLUS
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
-CFX_GdiFontCache::CFX_GdiFontCache() : m_GlyphMap(128) {}
-CFX_GdiFontCache::~CFX_GdiFontCache() {
- FX_POSITION pos = m_GlyphMap.GetStartPosition();
- int32_t iGlyph;
- FX_LPGDIGOCACHE pGlyph;
- while (pos != NULL) {
- pGlyph = NULL;
- m_GlyphMap.GetNextAssoc(pos, (void*&)iGlyph, (void*&)pGlyph);
- if (pGlyph != NULL) {
- FX_Free(pGlyph->pOutline);
- FX_Free(pGlyph);
- }
- }
- m_GlyphMap.RemoveAll();
-}
-void CFX_GdiFontCache::SetCachedGlyphOutline(FX_DWORD dwGlyph,
- const GLYPHMETRICS& gm,
- uint8_t* pOutline) {
- FXSYS_assert(pOutline != NULL);
- FX_LPGDIGOCACHE pGlyph = FX_Alloc(FX_GDIGOCACHE, 1);
- pGlyph->gm = gm;
- pGlyph->pOutline = pOutline;
- m_GlyphMap.SetAt((void*)dwGlyph, (void*)pGlyph);
-}
-FX_LPCGDIGOCACHE CFX_GdiFontCache::GetCachedGlyphOutline(
- FX_DWORD dwGlyph) const {
- FX_LPCGDIGOCACHE pGlyph = NULL;
- if (!m_GlyphMap.Lookup((void*)dwGlyph, (void*&)pGlyph)) {
- return FALSE;
- }
- return pGlyph;
-}
-IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage,
- IFX_FontMgr* pFontMgr) {
- CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
- if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-}
-IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer,
- int32_t iLength,
- IFX_FontMgr* pFontMgr) {
- CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
- if (!pFont->LoadFont(pBuffer, iLength)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-}
-IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName,
- IFX_FontMgr* pFontMgr) {
- CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
- if (!pFont->LoadFont(pszFileName)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-}
-IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream,
- IFX_FontMgr* pFontMgr,
- FX_BOOL bSaveStream) {
- CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
- if (!pFont->LoadFont(pFontStream)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-}
-IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont, IFX_FontMgr* pFontMgr) {
- FXSYS_assert(FALSE);
- return NULL;
-}
-#define FX_GDIFONT_FONTCACHESIZE 8
-CFX_GdiFont::CFX_GdiFont(IFX_FontMgr* pFontMgr)
- : m_pFontMgr(pFontMgr),
- m_iRefCount(1),
- m_WidthCache(1024),
- m_hOldFont(NULL),
- m_hFont(NULL),
- m_hDC(NULL),
- m_wsFontFileName(),
- m_FontFamilies(),
- m_hRes(NULL),
- m_dwStyles(0),
- m_SubstFonts(),
- m_FontMapper(16),
- m_FontCache(FX_GDIFONT_FONTCACHESIZE) {
- m_hDC = ::CreateCompatibleDC(NULL);
- FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
- FXSYS_assert(m_hDC != NULL);
-}
-CFX_GdiFont::~CFX_GdiFont() {
- int32_t iCount = m_SubstFonts.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
- pFont->Release();
- }
- m_SubstFonts.RemoveAll();
- m_FontMapper.RemoveAll();
- if (m_hFont != NULL) {
- ::SelectObject(m_hDC, m_hOldFont);
- ::DeleteObject(m_hFont);
- }
- ::DeleteDC(m_hDC);
- if (m_hRes != NULL) {
- if (m_wsFontFileName.GetLength() > 0) {
- ::RemoveFontResourceW((const FX_WCHAR*)m_wsFontFileName);
- } else {
- ::RemoveFontMemResourceEx(m_hRes);
- }
- }
- m_WidthCache.RemoveAll();
- ClearCache();
-}
-void CFX_GdiFont::ClearCache() {
- int32_t iCount = m_SubstFonts.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
- ((CFX_GdiFont*)pFont)->ClearCache();
- }
- FX_POSITION pos = m_FontCache.GetStartPosition();
- FX_DWORD dwMAT2;
- CFX_GdiFontCache* pCache;
- while (pos != NULL) {
- pCache = NULL;
- m_FontCache.GetNextAssoc(pos, (void*&)dwMAT2, (void*&)pCache);
- if (pCache != NULL) {
- delete pCache;
- }
- }
- m_FontCache.RemoveAll();
-}
-void CFX_GdiFont::Release() {
- if (--m_iRefCount < 1) {
- if (m_pFontMgr != NULL) {
- m_pFontMgr->RemoveFont(this);
- }
- delete this;
- }
-}
-IFX_Font* CFX_GdiFont::Retain() {
- ++m_iRefCount;
- return this;
-}
-FX_BOOL CFX_GdiFont::LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage) {
- FXSYS_assert(m_hFont == NULL);
- LOGFONTW lf;
- FX_memset(&lf, 0, sizeof(lf));
- lf.lfHeight = -1000;
- lf.lfWeight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FW_BOLD : FW_NORMAL;
- lf.lfItalic = (dwFontStyles & FX_FONTSTYLE_Italic) != 0;
- lf.lfPitchAndFamily =
- (dwFontStyles & FX_FONTSTYLE_FixedPitch) ? FIXED_PITCH : VARIABLE_PITCH;
- if (dwFontStyles & FX_FONTSTYLE_Serif) {
- lf.lfPitchAndFamily |= FF_ROMAN;
- }
- if (dwFontStyles & FX_FONTSTYLE_Script) {
- lf.lfPitchAndFamily |= FF_SCRIPT;
- }
- if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
- lf.lfCharSet = SYMBOL_CHARSET;
- } else {
- FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
- lf.lfCharSet = wCharSet != 0xFFFF ? (uint8_t)wCharSet : DEFAULT_CHARSET;
- }
- if (pszFontFamily == NULL) {
- lf.lfFaceName[0] = L'\0';
- } else {
- FXSYS_wcsncpy(lf.lfFaceName, pszFontFamily, 31);
- }
- return LoadFont(lf);
-}
-FX_BOOL CFX_GdiFont::LoadFont(const uint8_t* pBuffer, int32_t iLength) {
- FXSYS_assert(m_hFont == NULL && pBuffer != NULL && iLength > 0);
- Gdiplus::PrivateFontCollection pfc;
- if (pfc.AddMemoryFont(pBuffer, iLength) != Gdiplus::Ok) {
- return FALSE;
- }
- if (GetFontFamilies(pfc) < 1) {
- return FALSE;
- }
- FX_DWORD dwCount = 0;
- m_hRes = ::AddFontMemResourceEx((void*)pBuffer, iLength, 0, &dwCount);
- if (m_hRes == NULL) {
- return FALSE;
- }
- CFX_WideString wsFamily = m_FontFamilies[0];
- m_hFont =
- ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0,
- 0, 0, 0, (const FX_WCHAR*)wsFamily);
- if (m_hFont == NULL) {
- ::RemoveFontMemResourceEx(m_hRes);
- m_hRes = NULL;
- return FALSE;
- }
- RetrieveFontStyles();
- m_hOldFont = ::SelectObject(m_hDC, m_hFont);
- ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
- return TRUE;
-}
-FX_BOOL CFX_GdiFont::LoadFont(const FX_WCHAR* pszFileName) {
- FXSYS_assert(m_hFont == NULL && pszFileName != NULL);
- Gdiplus::PrivateFontCollection pfc;
- if (pfc.AddFontFile(pszFileName) != Gdiplus::Ok) {
- return FALSE;
- }
- if (GetFontFamilies(pfc) < 1) {
- return FALSE;
- }
- m_wsFontFileName = pszFileName;
- m_hRes = (HANDLE)::AddFontResourceW(pszFileName);
- if (m_hRes == NULL) {
- return FALSE;
- }
- CFX_WideString wsFamily = m_FontFamilies[0];
- m_hFont =
- ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0,
- 0, 0, 0, (const FX_WCHAR*)wsFamily);
- if (m_hFont == NULL) {
- ::RemoveFontResourceW(pszFileName);
- m_hRes = NULL;
- return FALSE;
- }
- RetrieveFontStyles();
- ::SelectObject(m_hDC, m_hFont);
- ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
- return TRUE;
-}
-FX_BOOL CFX_GdiFont::LoadFont(IFX_Stream* pFontStream) {
- FXSYS_assert(m_hFont == NULL && pFontStream != NULL);
- int32_t iLength = pFontStream->GetLength();
- if (iLength < 1) {
- return FALSE;
- }
- uint8_t* pBuf = FX_Alloc(uint8_t, iLength);
- iLength = pFontStream->ReadData(pBuf, iLength);
- FX_BOOL bRet = LoadFont(pBuf, iLength);
- FX_Free(pBuf);
- return bRet;
-}
-FX_BOOL CFX_GdiFont::LoadFont(const LOGFONTW& lf) {
- FXSYS_assert(m_hFont == NULL);
- m_hFont = ::CreateFontIndirectW((LPLOGFONTW)&lf);
- if (m_hFont == NULL) {
- return FALSE;
- }
- RetrieveFontStyles();
- ::SelectObject(m_hDC, m_hFont);
- ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
- return TRUE;
-}
-int32_t CFX_GdiFont::GetFontFamilies(Gdiplus::FontCollection& fc) {
- int32_t iCount = fc.GetFamilyCount();
- if (iCount < 1) {
- return iCount;
- }
- Gdiplus::FontFamily* pFontFamilies = FX_Alloc(Gdiplus::FontFamily, iCount);
- int32_t iFind = 0;
- fc.GetFamilies(iCount, pFontFamilies, &iFind);
- for (int32_t i = 0; i < iCount; i++) {
- CFX_WideString wsFamilyName;
- FX_WCHAR* pName = wsFamilyName.GetBuffer(LF_FACESIZE);
- pFontFamilies[i].GetFamilyName(pName);
- wsFamilyName.ReleaseBuffer();
- m_FontFamilies.Add(wsFamilyName);
- }
- FX_Free(pFontFamilies);
- return iCount;
-}
-void CFX_GdiFont::RetrieveFontStyles() {
- FXSYS_assert(m_hFont != NULL);
- FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
- ::GetObjectW(m_hFont, sizeof(m_LogFont), &m_LogFont);
- m_dwStyles = FX_GetGdiFontStyles(m_LogFont);
-}
-void CFX_GdiFont::GetFamilyName(CFX_WideString& wsFamily) const {
- FXSYS_assert(m_hFont != NULL);
- wsFamily = m_LogFont.lfFaceName;
-}
-FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode) {
- iWidth = (int32_t)(int16_t)m_WidthCache.GetAt(wUnicode, 0);
- if (iWidth == 0 || iWidth == -1) {
- IFX_Font* pFont = NULL;
- int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
- if (iGlyph != 0xFFFF && pFont != NULL) {
- if (pFont == (IFX_Font*)this) {
- if (!::GetCharWidthI(m_hDC, iGlyph, 1, NULL, &iWidth)) {
- iWidth = -1;
- }
- } else if (((CFX_GdiFont*)pFont)
- ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
- return TRUE;
- }
- } else {
- iWidth = -1;
- }
- Lock();
- m_WidthCache.SetAtGrow(wUnicode, (int16_t)iWidth);
- Unlock();
- }
- return iWidth > 0;
-}
-FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bCharCode) {
- return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
-}
-int32_t CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode,
- FX_BOOL bRecursive,
- IFX_Font** ppFont,
- FX_BOOL bCharCode) {
- int32_t iGlyph = 0XFFFF;
- if (::GetGlyphIndicesW(m_hDC, &wUnicode, 1, (LPWORD)&iGlyph,
- GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR &&
- iGlyph != 0xFFFF) {
- if (ppFont != NULL) {
- *ppFont = (IFX_Font*)this;
- }
- return iGlyph;
- }
- FX_LPCFONTUSB pFontUSB = FX_GetUnicodeBitField(wUnicode);
- if (pFontUSB == NULL) {
- return 0xFFFF;
- }
- FX_WORD wBitField = pFontUSB->wBitField;
- if (wBitField >= 128) {
- return 0xFFFF;
- }
- IFX_Font* pFont = NULL;
- m_FontMapper.Lookup((void*)wBitField, (void*&)pFont);
- if (pFont != NULL && pFont != (IFX_Font*)this) {
- iGlyph =
- ((CFX_GdiFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
- if (iGlyph != 0xFFFF) {
- int32_t i = m_SubstFonts.Find(pFont);
- if (i > -1) {
- iGlyph |= ((i + 1) << 24);
- if (ppFont != NULL) {
- *ppFont = pFont;
- }
- return iGlyph;
- }
- }
- }
- if (m_pFontMgr != NULL && bRecursive) {
- IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode(wUnicode, m_dwStyles,
- m_LogFont.lfFaceName);
- if (pFont != NULL) {
- if (pFont == (IFX_Font*)this) {
- pFont->Release();
- return 0xFFFF;
- }
- m_FontMapper.SetAt((void*)wBitField, (void*)pFont);
- int32_t i = m_SubstFonts.GetSize();
- m_SubstFonts.Add(pFont);
- iGlyph = ((CFX_GdiFont*)pFont)
- ->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
- if (iGlyph != 0xFFFF) {
- iGlyph |= ((i + 1) << 24);
- if (ppFont != NULL) {
- *ppFont = pFont;
- }
- return iGlyph;
- }
- }
- }
- return 0xFFFF;
-}
-int32_t CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) {
- return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
-}
-int32_t CFX_GdiFont::GetAscent() const {
- return m_OutlineTM.otmAscent;
-}
-int32_t CFX_GdiFont::GetDescent() const {
- return m_OutlineTM.otmDescent;
-}
-FX_BOOL CFX_GdiFont::GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bCharCode) {
- int32_t iGlyphIndex = GetGlyphIndex(wUnicode, bCharCode);
- if (iGlyphIndex == 0xFFFF) {
- return FALSE;
- }
- IFX_Font* pFont = GetSubstFont(iGlyphIndex);
- if (pFont == NULL) {
- return FALSE;
- }
- GLYPHMETRICS gm;
- iGlyphIndex &= 0x00FFFFFF;
- static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
- if (::GetGlyphOutlineW(((CFX_GdiFont*)pFont)->m_hDC, iGlyphIndex,
- GGO_GLYPH_INDEX | GGO_METRICS, &gm, 0, NULL,
- &mat2) != GDI_ERROR) {
- bbox.left = gm.gmptGlyphOrigin.x;
- bbox.top = gm.gmptGlyphOrigin.y;
- bbox.width = gm.gmBlackBoxX;
- bbox.height = gm.gmBlackBoxY;
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CFX_GdiFont::GetBBox(CFX_Rect& bbox) {
- bbox.left = m_OutlineTM.otmrcFontBox.left;
- bbox.top = m_OutlineTM.otmrcFontBox.top;
- bbox.width = m_OutlineTM.otmrcFontBox.right - m_OutlineTM.otmrcFontBox.left;
- bbox.height = m_OutlineTM.otmrcFontBox.bottom - m_OutlineTM.otmrcFontBox.top;
- return TRUE;
-}
-int32_t CFX_GdiFont::GetItalicAngle() const {
- return m_OutlineTM.otmItalicAngle / 10;
-}
-void CFX_GdiFont::Reset() {
- Lock();
- m_WidthCache.RemoveAll();
- ClearCache();
- Unlock();
-}
-IFX_Font* CFX_GdiFont::GetSubstFont(int32_t iGlyphIndex) const {
- int32_t iHigher = (iGlyphIndex & 0x7F000000) >> 24;
- if (iHigher == 0) {
- return (IFX_Font*)this;
- }
- if (iHigher > m_SubstFonts.GetSize()) {
- return (IFX_Font*)this;
- }
- return (IFX_Font*)m_SubstFonts[iHigher - 1];
-}
-FX_DWORD CFX_GdiFont::GetGlyphDIBits(int32_t iGlyphIndex,
- FX_ARGB argb,
- const MAT2* pMatrix,
- GLYPHMETRICS& gm,
- void* pBuffer,
- FX_DWORD bufSize) {
- static const UINT uFormat = GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP;
- IFX_Font* pFont = GetSubstFont(iGlyphIndex);
- if (pFont == NULL) {
- return 0;
- }
- if (pFont != (IFX_Font*)this) {
- return ((CFX_GdiFont*)pFont)
- ->GetGlyphDIBits(iGlyphIndex & 0x00FFFFFF, argb, pMatrix, gm, pBuffer,
- bufSize);
- }
- uint8_t* pGlyphOutline = NULL;
- FXSYS_assert(pMatrix != NULL);
- FX_DWORD dwMAT2 = GetMAT2HashCode((const FIXED*)pMatrix);
- CFX_GdiFontCache* pCache = NULL;
- if (m_FontCache.Lookup((void*)dwMAT2, (void*&)pCache) && pCache != NULL) {
- FX_LPCGDIGOCACHE pGO = pCache->GetCachedGlyphOutline(iGlyphIndex);
- if (pGO != NULL) {
- gm = pGO->gm;
- pGlyphOutline = pGO->pOutline;
- }
- }
- if (pGlyphOutline == NULL) {
- FX_DWORD dwGlyphSize =
- ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, 0, NULL, pMatrix);
- if (dwGlyphSize == 0 || dwGlyphSize == GDI_ERROR) {
- return 0;
- }
- pGlyphOutline = FX_Alloc(uint8_t, dwGlyphSize);
- ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, dwGlyphSize,
- pGlyphOutline, pMatrix);
- if (pCache == NULL) {
- pCache = new CFX_GdiFontCache;
- if (m_FontCache.GetCount() >= FX_GDIFONT_FONTCACHESIZE) {
- ClearCache();
- }
- m_FontCache.SetAt((void*)dwMAT2, (void*)pCache);
- }
- pCache->SetCachedGlyphOutline(iGlyphIndex, gm, pGlyphOutline);
- }
- FX_DWORD dwDibSize = gm.gmBlackBoxX * 4 * gm.gmBlackBoxY;
- if (pBuffer == NULL || bufSize < dwDibSize) {
- return dwDibSize;
- }
- CreateGlyphBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, pGlyphOutline,
- (FX_DWORD*)pBuffer, argb);
- return dwDibSize;
-}
-FX_DWORD CFX_GdiFont::GetHashCode() const {
- return FX_GetFontHashCode(FX_GetCodePageFromCharset(m_LogFont.lfCharSet),
- FX_GetGdiFontStyles(m_LogFont));
-}
-FX_DWORD CFX_GdiFont::GetMAT2HashCode(const FIXED* pFixed) {
- FXSYS_assert(pFixed != NULL);
- FX_DWORD dwHash1 = 0, dwHash2 = 5381, dwRet;
- for (int i = 0; i < 4; i++) {
- dwRet = *((const FX_DWORD*)pFixed);
- dwHash1 = 1313 * dwHash1 + dwRet;
- dwHash2 += (dwHash2 << 5) + dwRet;
- pFixed++;
- }
- return ((dwHash1 & 0x0000FFFF) << 16) | (dwHash2 & 0x0000FFFF);
-}
-void CFX_GdiFont::CreateGlyphBitmap(int32_t iWidth,
- int32_t iHeight,
- uint8_t* pOutline,
- FX_DWORD* pDIB,
- FX_ARGB argb) {
- int32_t padding = ((iWidth + 3) / 4) * 4 - iWidth;
- FX_DWORD alpha;
- int32_t i, j;
- for (j = iHeight - 1; j >= 0; --j) {
- for (i = iWidth - 1; i >= 0; --i) {
- if ((alpha = *pOutline++) == 0) {
- *pDIB++ = 0;
- } else {
- alpha = (argb >> 24) * (alpha * 4 - 1) / 256;
- *pDIB++ = (alpha << 24) | (argb & 0x00FFFFFF);
- }
- }
- pOutline += padding;
- }
-}
-#endif
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_gdifont.h"
+#include "fx_stdfontmgr.h"
+#ifdef _FXPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+CFX_GdiFontCache::CFX_GdiFontCache() : m_GlyphMap(128) {}
+CFX_GdiFontCache::~CFX_GdiFontCache() {
+ FX_POSITION pos = m_GlyphMap.GetStartPosition();
+ int32_t iGlyph;
+ FX_LPGDIGOCACHE pGlyph;
+ while (pos != NULL) {
+ pGlyph = NULL;
+ m_GlyphMap.GetNextAssoc(pos, (void*&)iGlyph, (void*&)pGlyph);
+ if (pGlyph != NULL) {
+ FX_Free(pGlyph->pOutline);
+ FX_Free(pGlyph);
+ }
+ }
+ m_GlyphMap.RemoveAll();
+}
+void CFX_GdiFontCache::SetCachedGlyphOutline(FX_DWORD dwGlyph,
+ const GLYPHMETRICS& gm,
+ uint8_t* pOutline) {
+ FXSYS_assert(pOutline != NULL);
+ FX_LPGDIGOCACHE pGlyph = FX_Alloc(FX_GDIGOCACHE, 1);
+ pGlyph->gm = gm;
+ pGlyph->pOutline = pOutline;
+ m_GlyphMap.SetAt((void*)dwGlyph, (void*)pGlyph);
+}
+FX_LPCGDIGOCACHE CFX_GdiFontCache::GetCachedGlyphOutline(
+ FX_DWORD dwGlyph) const {
+ FX_LPCGDIGOCACHE pGlyph = NULL;
+ if (!m_GlyphMap.Lookup((void*)dwGlyph, (void*&)pGlyph)) {
+ return FALSE;
+ }
+ return pGlyph;
+}
+IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage,
+ IFX_FontMgr* pFontMgr) {
+ CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer,
+ int32_t iLength,
+ IFX_FontMgr* pFontMgr) {
+ CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pBuffer, iLength)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName,
+ IFX_FontMgr* pFontMgr) {
+ CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pszFileName)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream,
+ IFX_FontMgr* pFontMgr,
+ FX_BOOL bSaveStream) {
+ CFX_GdiFont* pFont = new CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pFontStream)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont, IFX_FontMgr* pFontMgr) {
+ FXSYS_assert(FALSE);
+ return NULL;
+}
+#define FX_GDIFONT_FONTCACHESIZE 8
+CFX_GdiFont::CFX_GdiFont(IFX_FontMgr* pFontMgr)
+ : m_pFontMgr(pFontMgr),
+ m_iRefCount(1),
+ m_WidthCache(1024),
+ m_hOldFont(NULL),
+ m_hFont(NULL),
+ m_hDC(NULL),
+ m_wsFontFileName(),
+ m_FontFamilies(),
+ m_hRes(NULL),
+ m_dwStyles(0),
+ m_SubstFonts(),
+ m_FontMapper(16),
+ m_FontCache(FX_GDIFONT_FONTCACHESIZE) {
+ m_hDC = ::CreateCompatibleDC(NULL);
+ FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
+ FXSYS_assert(m_hDC != NULL);
+}
+CFX_GdiFont::~CFX_GdiFont() {
+ int32_t iCount = m_SubstFonts.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
+ pFont->Release();
+ }
+ m_SubstFonts.RemoveAll();
+ m_FontMapper.RemoveAll();
+ if (m_hFont != NULL) {
+ ::SelectObject(m_hDC, m_hOldFont);
+ ::DeleteObject(m_hFont);
+ }
+ ::DeleteDC(m_hDC);
+ if (m_hRes != NULL) {
+ if (m_wsFontFileName.GetLength() > 0) {
+ ::RemoveFontResourceW((const FX_WCHAR*)m_wsFontFileName);
+ } else {
+ ::RemoveFontMemResourceEx(m_hRes);
+ }
+ }
+ m_WidthCache.RemoveAll();
+ ClearCache();
+}
+void CFX_GdiFont::ClearCache() {
+ int32_t iCount = m_SubstFonts.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
+ ((CFX_GdiFont*)pFont)->ClearCache();
+ }
+ FX_POSITION pos = m_FontCache.GetStartPosition();
+ FX_DWORD dwMAT2;
+ CFX_GdiFontCache* pCache;
+ while (pos != NULL) {
+ pCache = NULL;
+ m_FontCache.GetNextAssoc(pos, (void*&)dwMAT2, (void*&)pCache);
+ if (pCache != NULL) {
+ delete pCache;
+ }
+ }
+ m_FontCache.RemoveAll();
+}
+void CFX_GdiFont::Release() {
+ if (--m_iRefCount < 1) {
+ if (m_pFontMgr != NULL) {
+ m_pFontMgr->RemoveFont(this);
+ }
+ delete this;
+ }
+}
+IFX_Font* CFX_GdiFont::Retain() {
+ ++m_iRefCount;
+ return this;
+}
+FX_BOOL CFX_GdiFont::LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage) {
+ FXSYS_assert(m_hFont == NULL);
+ LOGFONTW lf;
+ FX_memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = -1000;
+ lf.lfWeight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FW_BOLD : FW_NORMAL;
+ lf.lfItalic = (dwFontStyles & FX_FONTSTYLE_Italic) != 0;
+ lf.lfPitchAndFamily =
+ (dwFontStyles & FX_FONTSTYLE_FixedPitch) ? FIXED_PITCH : VARIABLE_PITCH;
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ lf.lfPitchAndFamily |= FF_ROMAN;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ lf.lfPitchAndFamily |= FF_SCRIPT;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ lf.lfCharSet = SYMBOL_CHARSET;
+ } else {
+ FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
+ lf.lfCharSet = wCharSet != 0xFFFF ? (uint8_t)wCharSet : DEFAULT_CHARSET;
+ }
+ if (pszFontFamily == NULL) {
+ lf.lfFaceName[0] = L'\0';
+ } else {
+ FXSYS_wcsncpy(lf.lfFaceName, pszFontFamily, 31);
+ }
+ return LoadFont(lf);
+}
+FX_BOOL CFX_GdiFont::LoadFont(const uint8_t* pBuffer, int32_t iLength) {
+ FXSYS_assert(m_hFont == NULL && pBuffer != NULL && iLength > 0);
+ Gdiplus::PrivateFontCollection pfc;
+ if (pfc.AddMemoryFont(pBuffer, iLength) != Gdiplus::Ok) {
+ return FALSE;
+ }
+ if (GetFontFamilies(pfc) < 1) {
+ return FALSE;
+ }
+ FX_DWORD dwCount = 0;
+ m_hRes = ::AddFontMemResourceEx((void*)pBuffer, iLength, 0, &dwCount);
+ if (m_hRes == NULL) {
+ return FALSE;
+ }
+ CFX_WideString wsFamily = m_FontFamilies[0];
+ m_hFont =
+ ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0,
+ 0, 0, 0, (const FX_WCHAR*)wsFamily);
+ if (m_hFont == NULL) {
+ ::RemoveFontMemResourceEx(m_hRes);
+ m_hRes = NULL;
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ m_hOldFont = ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+FX_BOOL CFX_GdiFont::LoadFont(const FX_WCHAR* pszFileName) {
+ FXSYS_assert(m_hFont == NULL && pszFileName != NULL);
+ Gdiplus::PrivateFontCollection pfc;
+ if (pfc.AddFontFile(pszFileName) != Gdiplus::Ok) {
+ return FALSE;
+ }
+ if (GetFontFamilies(pfc) < 1) {
+ return FALSE;
+ }
+ m_wsFontFileName = pszFileName;
+ m_hRes = (HANDLE)::AddFontResourceW(pszFileName);
+ if (m_hRes == NULL) {
+ return FALSE;
+ }
+ CFX_WideString wsFamily = m_FontFamilies[0];
+ m_hFont =
+ ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0,
+ 0, 0, 0, (const FX_WCHAR*)wsFamily);
+ if (m_hFont == NULL) {
+ ::RemoveFontResourceW(pszFileName);
+ m_hRes = NULL;
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+FX_BOOL CFX_GdiFont::LoadFont(IFX_Stream* pFontStream) {
+ FXSYS_assert(m_hFont == NULL && pFontStream != NULL);
+ int32_t iLength = pFontStream->GetLength();
+ if (iLength < 1) {
+ return FALSE;
+ }
+ uint8_t* pBuf = FX_Alloc(uint8_t, iLength);
+ iLength = pFontStream->ReadData(pBuf, iLength);
+ FX_BOOL bRet = LoadFont(pBuf, iLength);
+ FX_Free(pBuf);
+ return bRet;
+}
+FX_BOOL CFX_GdiFont::LoadFont(const LOGFONTW& lf) {
+ FXSYS_assert(m_hFont == NULL);
+ m_hFont = ::CreateFontIndirectW((LPLOGFONTW)&lf);
+ if (m_hFont == NULL) {
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+int32_t CFX_GdiFont::GetFontFamilies(Gdiplus::FontCollection& fc) {
+ int32_t iCount = fc.GetFamilyCount();
+ if (iCount < 1) {
+ return iCount;
+ }
+ Gdiplus::FontFamily* pFontFamilies = FX_Alloc(Gdiplus::FontFamily, iCount);
+ int32_t iFind = 0;
+ fc.GetFamilies(iCount, pFontFamilies, &iFind);
+ for (int32_t i = 0; i < iCount; i++) {
+ CFX_WideString wsFamilyName;
+ FX_WCHAR* pName = wsFamilyName.GetBuffer(LF_FACESIZE);
+ pFontFamilies[i].GetFamilyName(pName);
+ wsFamilyName.ReleaseBuffer();
+ m_FontFamilies.Add(wsFamilyName);
+ }
+ FX_Free(pFontFamilies);
+ return iCount;
+}
+void CFX_GdiFont::RetrieveFontStyles() {
+ FXSYS_assert(m_hFont != NULL);
+ FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
+ ::GetObjectW(m_hFont, sizeof(m_LogFont), &m_LogFont);
+ m_dwStyles = FX_GetGdiFontStyles(m_LogFont);
+}
+void CFX_GdiFont::GetFamilyName(CFX_WideString& wsFamily) const {
+ FXSYS_assert(m_hFont != NULL);
+ wsFamily = m_LogFont.lfFaceName;
+}
+FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode) {
+ iWidth = (int32_t)(int16_t)m_WidthCache.GetAt(wUnicode, 0);
+ if (iWidth == 0 || iWidth == -1) {
+ IFX_Font* pFont = NULL;
+ int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ if (!::GetCharWidthI(m_hDC, iGlyph, 1, NULL, &iWidth)) {
+ iWidth = -1;
+ }
+ } else if (((CFX_GdiFont*)pFont)
+ ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ } else {
+ iWidth = -1;
+ }
+ Lock();
+ m_WidthCache.SetAtGrow(wUnicode, (int16_t)iWidth);
+ Unlock();
+ }
+ return iWidth > 0;
+}
+FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bCharCode) {
+ return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
+}
+int32_t CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode,
+ FX_BOOL bRecursive,
+ IFX_Font** ppFont,
+ FX_BOOL bCharCode) {
+ int32_t iGlyph = 0XFFFF;
+ if (::GetGlyphIndicesW(m_hDC, &wUnicode, 1, (LPWORD)&iGlyph,
+ GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR &&
+ iGlyph != 0xFFFF) {
+ if (ppFont != NULL) {
+ *ppFont = (IFX_Font*)this;
+ }
+ return iGlyph;
+ }
+ FX_LPCFONTUSB pFontUSB = FX_GetUnicodeBitField(wUnicode);
+ if (pFontUSB == NULL) {
+ return 0xFFFF;
+ }
+ FX_WORD wBitField = pFontUSB->wBitField;
+ if (wBitField >= 128) {
+ return 0xFFFF;
+ }
+ IFX_Font* pFont = NULL;
+ m_FontMapper.Lookup((void*)wBitField, (void*&)pFont);
+ if (pFont != NULL && pFont != (IFX_Font*)this) {
+ iGlyph =
+ ((CFX_GdiFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyph != 0xFFFF) {
+ int32_t i = m_SubstFonts.Find(pFont);
+ if (i > -1) {
+ iGlyph |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyph;
+ }
+ }
+ }
+ if (m_pFontMgr != NULL && bRecursive) {
+ IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode(wUnicode, m_dwStyles,
+ m_LogFont.lfFaceName);
+ if (pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ pFont->Release();
+ return 0xFFFF;
+ }
+ m_FontMapper.SetAt((void*)wBitField, (void*)pFont);
+ int32_t i = m_SubstFonts.GetSize();
+ m_SubstFonts.Add(pFont);
+ iGlyph = ((CFX_GdiFont*)pFont)
+ ->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyph != 0xFFFF) {
+ iGlyph |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyph;
+ }
+ }
+ }
+ return 0xFFFF;
+}
+int32_t CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) {
+ return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
+}
+int32_t CFX_GdiFont::GetAscent() const {
+ return m_OutlineTM.otmAscent;
+}
+int32_t CFX_GdiFont::GetDescent() const {
+ return m_OutlineTM.otmDescent;
+}
+FX_BOOL CFX_GdiFont::GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bCharCode) {
+ int32_t iGlyphIndex = GetGlyphIndex(wUnicode, bCharCode);
+ if (iGlyphIndex == 0xFFFF) {
+ return FALSE;
+ }
+ IFX_Font* pFont = GetSubstFont(iGlyphIndex);
+ if (pFont == NULL) {
+ return FALSE;
+ }
+ GLYPHMETRICS gm;
+ iGlyphIndex &= 0x00FFFFFF;
+ static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
+ if (::GetGlyphOutlineW(((CFX_GdiFont*)pFont)->m_hDC, iGlyphIndex,
+ GGO_GLYPH_INDEX | GGO_METRICS, &gm, 0, NULL,
+ &mat2) != GDI_ERROR) {
+ bbox.left = gm.gmptGlyphOrigin.x;
+ bbox.top = gm.gmptGlyphOrigin.y;
+ bbox.width = gm.gmBlackBoxX;
+ bbox.height = gm.gmBlackBoxY;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CFX_GdiFont::GetBBox(CFX_Rect& bbox) {
+ bbox.left = m_OutlineTM.otmrcFontBox.left;
+ bbox.top = m_OutlineTM.otmrcFontBox.top;
+ bbox.width = m_OutlineTM.otmrcFontBox.right - m_OutlineTM.otmrcFontBox.left;
+ bbox.height = m_OutlineTM.otmrcFontBox.bottom - m_OutlineTM.otmrcFontBox.top;
+ return TRUE;
+}
+int32_t CFX_GdiFont::GetItalicAngle() const {
+ return m_OutlineTM.otmItalicAngle / 10;
+}
+void CFX_GdiFont::Reset() {
+ Lock();
+ m_WidthCache.RemoveAll();
+ ClearCache();
+ Unlock();
+}
+IFX_Font* CFX_GdiFont::GetSubstFont(int32_t iGlyphIndex) const {
+ int32_t iHigher = (iGlyphIndex & 0x7F000000) >> 24;
+ if (iHigher == 0) {
+ return (IFX_Font*)this;
+ }
+ if (iHigher > m_SubstFonts.GetSize()) {
+ return (IFX_Font*)this;
+ }
+ return (IFX_Font*)m_SubstFonts[iHigher - 1];
+}
+FX_DWORD CFX_GdiFont::GetGlyphDIBits(int32_t iGlyphIndex,
+ FX_ARGB argb,
+ const MAT2* pMatrix,
+ GLYPHMETRICS& gm,
+ void* pBuffer,
+ FX_DWORD bufSize) {
+ static const UINT uFormat = GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP;
+ IFX_Font* pFont = GetSubstFont(iGlyphIndex);
+ if (pFont == NULL) {
+ return 0;
+ }
+ if (pFont != (IFX_Font*)this) {
+ return ((CFX_GdiFont*)pFont)
+ ->GetGlyphDIBits(iGlyphIndex & 0x00FFFFFF, argb, pMatrix, gm, pBuffer,
+ bufSize);
+ }
+ uint8_t* pGlyphOutline = NULL;
+ FXSYS_assert(pMatrix != NULL);
+ FX_DWORD dwMAT2 = GetMAT2HashCode((const FIXED*)pMatrix);
+ CFX_GdiFontCache* pCache = NULL;
+ if (m_FontCache.Lookup((void*)dwMAT2, (void*&)pCache) && pCache != NULL) {
+ FX_LPCGDIGOCACHE pGO = pCache->GetCachedGlyphOutline(iGlyphIndex);
+ if (pGO != NULL) {
+ gm = pGO->gm;
+ pGlyphOutline = pGO->pOutline;
+ }
+ }
+ if (pGlyphOutline == NULL) {
+ FX_DWORD dwGlyphSize =
+ ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, 0, NULL, pMatrix);
+ if (dwGlyphSize == 0 || dwGlyphSize == GDI_ERROR) {
+ return 0;
+ }
+ pGlyphOutline = FX_Alloc(uint8_t, dwGlyphSize);
+ ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, dwGlyphSize,
+ pGlyphOutline, pMatrix);
+ if (pCache == NULL) {
+ pCache = new CFX_GdiFontCache;
+ if (m_FontCache.GetCount() >= FX_GDIFONT_FONTCACHESIZE) {
+ ClearCache();
+ }
+ m_FontCache.SetAt((void*)dwMAT2, (void*)pCache);
+ }
+ pCache->SetCachedGlyphOutline(iGlyphIndex, gm, pGlyphOutline);
+ }
+ FX_DWORD dwDibSize = gm.gmBlackBoxX * 4 * gm.gmBlackBoxY;
+ if (pBuffer == NULL || bufSize < dwDibSize) {
+ return dwDibSize;
+ }
+ CreateGlyphBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, pGlyphOutline,
+ (FX_DWORD*)pBuffer, argb);
+ return dwDibSize;
+}
+FX_DWORD CFX_GdiFont::GetHashCode() const {
+ return FX_GetFontHashCode(FX_GetCodePageFromCharset(m_LogFont.lfCharSet),
+ FX_GetGdiFontStyles(m_LogFont));
+}
+FX_DWORD CFX_GdiFont::GetMAT2HashCode(const FIXED* pFixed) {
+ FXSYS_assert(pFixed != NULL);
+ FX_DWORD dwHash1 = 0, dwHash2 = 5381, dwRet;
+ for (int i = 0; i < 4; i++) {
+ dwRet = *((const FX_DWORD*)pFixed);
+ dwHash1 = 1313 * dwHash1 + dwRet;
+ dwHash2 += (dwHash2 << 5) + dwRet;
+ pFixed++;
+ }
+ return ((dwHash1 & 0x0000FFFF) << 16) | (dwHash2 & 0x0000FFFF);
+}
+void CFX_GdiFont::CreateGlyphBitmap(int32_t iWidth,
+ int32_t iHeight,
+ uint8_t* pOutline,
+ FX_DWORD* pDIB,
+ FX_ARGB argb) {
+ int32_t padding = ((iWidth + 3) / 4) * 4 - iWidth;
+ FX_DWORD alpha;
+ int32_t i, j;
+ for (j = iHeight - 1; j >= 0; --j) {
+ for (i = iWidth - 1; i >= 0; --i) {
+ if ((alpha = *pOutline++) == 0) {
+ *pDIB++ = 0;
+ } else {
+ alpha = (argb >> 24) * (alpha * 4 - 1) / 256;
+ *pDIB++ = (alpha << 24) | (argb & 0x00FFFFFF);
+ }
+ }
+ pOutline += padding;
+ }
+}
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gdifont.h b/xfa/src/fgas/src/font/fx_gdifont.h
index c50563b286..648a37c521 100644
--- a/xfa/src/fgas/src/font/fx_gdifont.h
+++ b/xfa/src/fgas/src/font/fx_gdifont.h
@@ -1,106 +1,106 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_GDIOBJECT_IMP
-#define _FX_GDIOBJECT_IMP
-#ifdef _FXPLUS
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
-typedef struct _FX_GDIGOCACHE {
- GLYPHMETRICS gm;
- uint8_t* pOutline;
-} FX_GDIGOCACHE, *FX_LPGDIGOCACHE;
-typedef FX_GDIGOCACHE const* FX_LPCGDIGOCACHE;
-class CFX_GdiFontCache {
- public:
- CFX_GdiFontCache();
- ~CFX_GdiFontCache();
- void SetCachedGlyphOutline(FX_DWORD dwGlyph,
- const GLYPHMETRICS& gm,
- uint8_t* pOutline);
- FX_LPCGDIGOCACHE GetCachedGlyphOutline(FX_DWORD dwGlyph) const;
-
- protected:
- CFX_MapPtrToPtr m_GlyphMap;
-};
-class CFX_GdiFont : public IFX_Font, public CFX_ThreadLock {
- public:
- CFX_GdiFont(IFX_FontMgr* pFontMgr);
- ~CFX_GdiFont();
- virtual void Release();
- virtual IFX_Font* Retain();
- FX_BOOL LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage);
- FX_BOOL LoadFont(const uint8_t* pBuffer, int32_t iLength);
- FX_BOOL LoadFont(const FX_WCHAR* pszFileName);
- FX_BOOL LoadFont(IFX_Stream* pFontStream);
- FX_BOOL LoadFont(const LOGFONTW& lf);
- virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0) {
- return NULL;
- }
- virtual void GetFamilyName(CFX_WideString& wsFamily) const;
- virtual FX_DWORD GetFontStyles() const { return m_dwStyles; }
- virtual uint8_t GetCharSet() const { return m_LogFont.lfCharSet; }
- virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bCharCode = FALSE);
- virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
- virtual int32_t GetAscent() const;
- virtual int32_t GetDescent() const;
- virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bCharCode = FALSE);
- virtual FX_BOOL GetBBox(CFX_Rect& bbox);
- virtual int32_t GetItalicAngle() const;
- virtual void Reset();
- FX_DWORD GetGlyphDIBits(int32_t iGlyphIndex,
- FX_ARGB argb,
- const MAT2* pMatrix,
- GLYPHMETRICS& gm,
- void* pBuffer,
- FX_DWORD bufSize);
- FX_DWORD GetHashCode() const;
-
- protected:
- IFX_FontMgr* m_pFontMgr;
- int32_t m_iRefCount;
- CFX_WordDiscreteArray m_WidthCache;
- OUTLINETEXTMETRICW m_OutlineTM;
- HGDIOBJ m_hOldFont;
- HFONT m_hFont;
- HDC m_hDC;
- LOGFONTW m_LogFont;
- CFX_WideString m_wsFontFileName;
- CFX_WideStringArray m_FontFamilies;
- HANDLE m_hRes;
- FX_DWORD m_dwStyles;
- CFX_PtrArray m_SubstFonts;
- CFX_MapPtrToPtr m_FontMapper;
- CFX_MapPtrToPtr m_FontCache;
- void ClearCache();
- int32_t GetFontFamilies(Gdiplus::FontCollection& fc);
- void RetrieveFontStyles();
- IFX_Font* GetSubstFont(int32_t iGlyphIndex) const;
- FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode = FALSE);
- int32_t GetGlyphIndex(FX_WCHAR wUnicode,
- FX_BOOL bRecursive,
- IFX_Font** ppFont,
- FX_BOOL bCharCode = FALSE);
- FX_DWORD GetMAT2HashCode(const FIXED* pFixed);
- void CreateGlyphBitmap(int32_t iWidth,
- int32_t iHeight,
- uint8_t* pOutline,
- FX_DWORD* pDIB,
- FX_ARGB argb);
- friend class CFX_GdiFontMgr;
-};
-#endif
-#endif
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_GDIOBJECT_IMP
+#define _FX_GDIOBJECT_IMP
+#ifdef _FXPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+typedef struct _FX_GDIGOCACHE {
+ GLYPHMETRICS gm;
+ uint8_t* pOutline;
+} FX_GDIGOCACHE, *FX_LPGDIGOCACHE;
+typedef FX_GDIGOCACHE const* FX_LPCGDIGOCACHE;
+class CFX_GdiFontCache {
+ public:
+ CFX_GdiFontCache();
+ ~CFX_GdiFontCache();
+ void SetCachedGlyphOutline(FX_DWORD dwGlyph,
+ const GLYPHMETRICS& gm,
+ uint8_t* pOutline);
+ FX_LPCGDIGOCACHE GetCachedGlyphOutline(FX_DWORD dwGlyph) const;
+
+ protected:
+ CFX_MapPtrToPtr m_GlyphMap;
+};
+class CFX_GdiFont : public IFX_Font, public CFX_ThreadLock {
+ public:
+ CFX_GdiFont(IFX_FontMgr* pFontMgr);
+ ~CFX_GdiFont();
+ virtual void Release();
+ virtual IFX_Font* Retain();
+ FX_BOOL LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage);
+ FX_BOOL LoadFont(const uint8_t* pBuffer, int32_t iLength);
+ FX_BOOL LoadFont(const FX_WCHAR* pszFileName);
+ FX_BOOL LoadFont(IFX_Stream* pFontStream);
+ FX_BOOL LoadFont(const LOGFONTW& lf);
+ virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0) {
+ return NULL;
+ }
+ virtual void GetFamilyName(CFX_WideString& wsFamily) const;
+ virtual FX_DWORD GetFontStyles() const { return m_dwStyles; }
+ virtual uint8_t GetCharSet() const { return m_LogFont.lfCharSet; }
+ virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bCharCode = FALSE);
+ virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
+ virtual int32_t GetAscent() const;
+ virtual int32_t GetDescent() const;
+ virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bCharCode = FALSE);
+ virtual FX_BOOL GetBBox(CFX_Rect& bbox);
+ virtual int32_t GetItalicAngle() const;
+ virtual void Reset();
+ FX_DWORD GetGlyphDIBits(int32_t iGlyphIndex,
+ FX_ARGB argb,
+ const MAT2* pMatrix,
+ GLYPHMETRICS& gm,
+ void* pBuffer,
+ FX_DWORD bufSize);
+ FX_DWORD GetHashCode() const;
+
+ protected:
+ IFX_FontMgr* m_pFontMgr;
+ int32_t m_iRefCount;
+ CFX_WordDiscreteArray m_WidthCache;
+ OUTLINETEXTMETRICW m_OutlineTM;
+ HGDIOBJ m_hOldFont;
+ HFONT m_hFont;
+ HDC m_hDC;
+ LOGFONTW m_LogFont;
+ CFX_WideString m_wsFontFileName;
+ CFX_WideStringArray m_FontFamilies;
+ HANDLE m_hRes;
+ FX_DWORD m_dwStyles;
+ CFX_PtrArray m_SubstFonts;
+ CFX_MapPtrToPtr m_FontMapper;
+ CFX_MapPtrToPtr m_FontCache;
+ void ClearCache();
+ int32_t GetFontFamilies(Gdiplus::FontCollection& fc);
+ void RetrieveFontStyles();
+ IFX_Font* GetSubstFont(int32_t iGlyphIndex) const;
+ FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode = FALSE);
+ int32_t GetGlyphIndex(FX_WCHAR wUnicode,
+ FX_BOOL bRecursive,
+ IFX_Font** ppFont,
+ FX_BOOL bCharCode = FALSE);
+ FX_DWORD GetMAT2HashCode(const FIXED* pFixed);
+ void CreateGlyphBitmap(int32_t iWidth,
+ int32_t iHeight,
+ uint8_t* pOutline,
+ FX_DWORD* pDIB,
+ FX_ARGB argb);
+ friend class CFX_GdiFontMgr;
+};
+#endif
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gefont.cpp b/xfa/src/fgas/src/font/fx_gefont.cpp
index f76444f68f..93f2b7bfc2 100644
--- a/xfa/src/fgas/src/font/fx_gefont.cpp
+++ b/xfa/src/fgas/src/font/fx_gefont.cpp
@@ -1,588 +1,588 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_gefont.h"
-#include "fx_fontutils.h"
-#ifndef _FXPLUS
-IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage,
- IFX_FontMgr* pFontMgr) {
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- if (NULL != pFontMgr) {
- return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
- }
- return NULL;
-#else
- CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
- if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-#endif
-}
-IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer,
- int32_t iLength,
- IFX_FontMgr* pFontMgr) {
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- if (NULL != pFontMgr) {
- return pFontMgr->LoadFont(pBuffer, iLength, 0, NULL);
- }
- return NULL;
-#else
- CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
- if (!pFont->LoadFont(pBuffer, iLength)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-#endif
-}
-IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName,
- IFX_FontMgr* pFontMgr) {
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- if (NULL != pFontMgr) {
- return pFontMgr->LoadFont(pszFileName, 0, NULL);
- }
- return NULL;
-#else
- CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
- if (!pFont->LoadFont(pszFileName)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-#endif
-}
-IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream,
- IFX_FontMgr* pFontMgr,
- FX_BOOL bSaveStream) {
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- if (NULL != pFontMgr) {
- return pFontMgr->LoadFont(pFontStream, 0, NULL);
- }
- return NULL;
-#else
- CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
- if (!pFont->LoadFont(pFontStream, bSaveStream)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-#endif
-}
-IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont,
- IFX_FontMgr* pFontMgr,
- FX_BOOL bTakeOver) {
- CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
- if (!pFont->LoadFont(pExtFont, bTakeOver)) {
- pFont->Release();
- return NULL;
- }
- return pFont;
-}
-CFX_GEFont::CFX_GEFont(IFX_FontMgr* pFontMgr)
- : CFX_ThreadLock(),
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- m_bUseLogFontStyle(FALSE),
- m_dwLogFontStyle(0),
-#endif
- m_pFont(NULL),
- m_pFontMgr(pFontMgr),
- m_iRefCount(1),
- m_bExtFont(FALSE),
- m_pStream(NULL),
- m_pFileRead(NULL),
- m_pFontEncoding(NULL),
- m_pCharWidthMap(NULL),
- m_pRectArray(NULL),
- m_pBBoxMap(NULL),
- m_pProvider(NULL),
- m_wCharSet(0xFFFF),
- m_SubstFonts(),
- m_FontMapper(16) {
-}
-
-CFX_GEFont::CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles)
- : CFX_ThreadLock(),
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- m_bUseLogFontStyle(FALSE),
- m_dwLogFontStyle(0),
-#endif
- m_pFont(NULL),
- m_pFontMgr(src.m_pFontMgr),
- m_iRefCount(1),
- m_bExtFont(FALSE),
- m_pStream(NULL),
- m_pFileRead(NULL),
- m_pFontEncoding(NULL),
- m_pCharWidthMap(NULL),
- m_pRectArray(NULL),
- m_pBBoxMap(NULL),
- m_pProvider(NULL),
- m_wCharSet(0xFFFF),
- m_SubstFonts(),
- m_FontMapper(16) {
- m_pFont = new CFX_Font;
- FXSYS_assert(m_pFont != NULL);
- FXSYS_assert(src.m_pFont != NULL);
- m_pFont->LoadClone(src.m_pFont);
- CFX_SubstFont* pSubst = m_pFont->GetSubstFont();
- if (!pSubst) {
- pSubst = new CFX_SubstFont;
- m_pFont->SetSubstFont(pSubst);
- }
- pSubst->m_Weight =
- (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
- if (dwFontStyles & FX_FONTSTYLE_Italic) {
- pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC;
- }
- InitFont();
-}
-CFX_GEFont::~CFX_GEFont() {
- int32_t iCount = m_SubstFonts.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
- pFont->Release();
- }
- m_SubstFonts.RemoveAll();
- m_FontMapper.RemoveAll();
- if (m_pFileRead != NULL) {
- m_pFileRead->Release();
- }
- if (m_pStream != NULL) {
- m_pStream->Release();
- }
- if (m_pFontEncoding != NULL) {
- delete m_pFontEncoding;
- }
- if (m_pCharWidthMap != NULL) {
- delete m_pCharWidthMap;
- }
- if (m_pRectArray != NULL) {
- delete m_pRectArray;
- }
- if (m_pBBoxMap != NULL) {
- delete m_pBBoxMap;
- }
- if (m_pFont != NULL && !m_bExtFont) {
- delete m_pFont;
- }
-}
-void CFX_GEFont::Release() {
- if (--m_iRefCount < 1) {
- if (m_pFontMgr != NULL) {
- m_pFontMgr->RemoveFont(this);
- }
- delete this;
- }
-}
-IFX_Font* CFX_GEFont::Retain() {
- ++m_iRefCount;
- return this;
-}
-FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage) {
- if (m_pFont) {
- return FALSE;
- }
- Lock();
- CFX_ByteString csFontFamily;
- if (pszFontFamily != NULL) {
- csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily);
- }
- FX_DWORD dwFlags = 0;
- if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
- dwFlags |= FXFONT_FIXED_PITCH;
- }
- if (dwFontStyles & FX_FONTSTYLE_Serif) {
- dwFlags |= FXFONT_SERIF;
- }
- if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
- dwFlags |= FXFONT_SYMBOLIC;
- }
- if (dwFontStyles & FX_FONTSTYLE_Script) {
- dwFlags |= FXFONT_SCRIPT;
- }
- if (dwFontStyles & FX_FONTSTYLE_Italic) {
- dwFlags |= FXFONT_ITALIC;
- }
- if (dwFontStyles & FX_FONTSTYLE_Bold) {
- dwFlags |= FXFONT_BOLD;
- }
- if (dwFontStyles & FX_FONTSTYLE_ExactMatch) {
- dwFlags |= FXFONT_EXACTMATCH;
- }
- int32_t iWeight =
- (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
- FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
- if (wCharSet == 0xFFFF) {
- wCharSet = FXSYS_GetACP();
- }
- m_wCharSet = wCharSet;
- m_pFont = new CFX_Font;
- if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) {
- csFontFamily += ",BoldItalic";
- } else if (dwFlags & FXFONT_BOLD) {
- csFontFamily += ",Bold";
- } else if (dwFlags & FXFONT_ITALIC) {
- csFontFamily += ",Italic";
- }
- m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage);
- FX_BOOL bRet = m_pFont->GetFace() != nullptr;
- if (bRet) {
- bRet = InitFont();
- }
- Unlock();
- return bRet;
-}
-FX_BOOL CFX_GEFont::LoadFont(const uint8_t* pBuffer, int32_t length) {
- if (m_pFont) {
- return FALSE;
- }
- Lock();
- m_pFont = new CFX_Font;
- FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length);
- if (bRet) {
- bRet = InitFont();
- }
- m_wCharSet = 0xFFFF;
- Unlock();
- return bRet;
-}
-FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFileName) {
- if (m_pFont || m_pStream || m_pFileRead) {
- return FALSE;
- }
- Lock();
- m_pStream = IFX_Stream::CreateStream(
- pszFileName, FX_STREAMACCESS_Binary | FX_STREAMACCESS_Read);
- m_pFileRead = FX_CreateFileRead(m_pStream);
- FX_BOOL bRet = FALSE;
- if (m_pStream && m_pFileRead) {
- m_pFont = new CFX_Font;
- bRet = m_pFont->LoadFile(m_pFileRead);
- if (bRet) {
- bRet = InitFont();
- } else {
- m_pFileRead->Release();
- m_pFileRead = nullptr;
- }
- }
- m_wCharSet = 0xFFFF;
- Unlock();
- return bRet;
-}
-FX_BOOL CFX_GEFont::LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream) {
- if (m_pFont || m_pFileRead || !pFontStream || pFontStream->GetLength() < 1) {
- return FALSE;
- }
- Lock();
- if (bSaveStream) {
- m_pStream = pFontStream;
- }
- m_pFileRead = FX_CreateFileRead(pFontStream);
- m_pFont = new CFX_Font;
- FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead);
- if (bRet) {
- bRet = InitFont();
- } else {
- m_pFileRead->Release();
- m_pFileRead = nullptr;
- }
- m_wCharSet = 0xFFFF;
- Unlock();
- return bRet;
-}
-FX_BOOL CFX_GEFont::LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver) {
- if (m_pFont || !pExtFont) {
- return FALSE;
- }
- Lock();
- m_pFont = pExtFont;
- FX_BOOL bRet = !!m_pFont;
- if (bRet) {
- m_bExtFont = !bTakeOver;
- bRet = InitFont();
- } else {
- m_bExtFont = TRUE;
- }
- m_wCharSet = 0xFFFF;
- Unlock();
- return bRet;
-}
-FX_BOOL CFX_GEFont::InitFont() {
- if (!m_pFont) {
- return FALSE;
- }
- if (!m_pFontEncoding) {
- m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont);
- if (!m_pFontEncoding) {
- return FALSE;
- }
- }
- if (!m_pCharWidthMap) {
- m_pCharWidthMap = new CFX_WordDiscreteArray(1024);
- }
- if (!m_pRectArray) {
- m_pRectArray = new CFX_RectMassArray(16);
- }
- if (!m_pBBoxMap) {
- m_pBBoxMap = new CFX_MapPtrToPtr(16);
- }
- return TRUE;
-}
-IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage) {
- if (GetFontStyles() == dwFontStyles) {
- return Retain();
- }
- return new CFX_GEFont(*this, dwFontStyles);
-}
-uint8_t CFX_GEFont::GetCharSet() const {
- if (m_wCharSet != 0xFFFF) {
- return (uint8_t)m_wCharSet;
- }
- if (!m_pFont->GetSubstFont()) {
- return FX_CHARSET_Default;
- }
- return m_pFont->GetSubstFont()->m_Charset;
-}
-void CFX_GEFont::GetFamilyName(CFX_WideString& wsFamily) const {
- if (!m_pFont->GetSubstFont() ||
- m_pFont->GetSubstFont()->m_Family.GetLength() == 0) {
- wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName());
- } else {
- wsFamily = CFX_WideString::FromLocal(m_pFont->GetSubstFont()->m_Family);
- }
-}
-void CFX_GEFont::GetPsName(CFX_WideString& wsName) const {
- wsName = m_pFont->GetPsName();
-}
-FX_DWORD CFX_GEFont::GetFontStyles() const {
- FXSYS_assert(m_pFont != NULL);
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- if (m_bUseLogFontStyle) {
- return m_dwLogFontStyle;
- }
-#endif
- FX_DWORD dwStyles = 0;
- if (!m_pFont->GetSubstFont()) {
- if (m_pFont->IsBold()) {
- dwStyles |= FX_FONTSTYLE_Bold;
- }
- if (m_pFont->IsItalic()) {
- dwStyles |= FX_FONTSTYLE_Italic;
- }
- } else {
- if (m_pFont->GetSubstFont()->m_Weight == FXFONT_FW_BOLD) {
- dwStyles |= FX_FONTSTYLE_Bold;
- }
- if (m_pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_ITALIC) {
- dwStyles |= FX_FONTSTYLE_Italic;
- }
- }
- return dwStyles;
-}
-FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bCharCode) {
- return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
-}
-FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode) {
- FXSYS_assert(m_pCharWidthMap != NULL);
- iWidth = m_pCharWidthMap->GetAt(wUnicode, 0);
- if (iWidth < 1) {
- if (!m_pProvider ||
- !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) {
- IFX_Font* pFont = NULL;
- int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
- if (iGlyph != 0xFFFF && pFont != NULL) {
- if (pFont == (IFX_Font*)this) {
- iWidth = m_pFont->GetGlyphWidth(iGlyph);
- if (iWidth < 0) {
- iWidth = -1;
- }
- } else if (((CFX_GEFont*)pFont)
- ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
- return TRUE;
- }
- } else {
- iWidth = -1;
- }
- }
- Lock();
- m_pCharWidthMap->SetAtGrow(wUnicode, (int16_t)iWidth);
- Unlock();
- } else if (iWidth == 65535) {
- iWidth = -1;
- }
- return iWidth > 0;
-}
-FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bCharCode) {
- return GetCharBBox(wUnicode, bbox, TRUE, bCharCode);
-}
-FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode) {
- FXSYS_assert(m_pRectArray != NULL);
- FXSYS_assert(m_pBBoxMap != NULL);
- void* pRect = NULL;
- if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
- IFX_Font* pFont = NULL;
- int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
- if (iGlyph != 0xFFFF && pFont != NULL) {
- if (pFont == (IFX_Font*)this) {
- FX_RECT rtBBox;
- if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
- Lock();
- CFX_Rect rt;
- rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
- int32_t index = m_pRectArray->Add(rt);
- pRect = m_pRectArray->GetPtrAt(index);
- m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
- Unlock();
- }
- } else if (((CFX_GEFont*)pFont)
- ->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) {
- return TRUE;
- }
- }
- }
- if (pRect == NULL) {
- return FALSE;
- }
- bbox = *(FX_LPCRECT)pRect;
- return TRUE;
-}
-FX_BOOL CFX_GEFont::GetBBox(CFX_Rect& bbox) {
- FX_RECT rt(0, 0, 0, 0);
- FX_BOOL bRet = m_pFont->GetBBox(rt);
- if (bRet) {
- bbox.left = rt.left;
- bbox.width = rt.Width();
- bbox.top = rt.bottom;
- bbox.height = -rt.Height();
- }
- return bRet;
-}
-int32_t CFX_GEFont::GetItalicAngle() const {
- if (!m_pFont->GetSubstFont()) {
- return 0;
- }
- return m_pFont->GetSubstFont()->m_ItalicAngle;
-}
-int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) {
- return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
-}
-int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode,
- FX_BOOL bRecursive,
- IFX_Font** ppFont,
- FX_BOOL bCharCode) {
- FXSYS_assert(m_pFontEncoding != NULL);
- int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
- if (iGlyphIndex > 0) {
- if (ppFont != NULL) {
- *ppFont = (IFX_Font*)this;
- }
- return iGlyphIndex;
- }
- FGAS_LPCFONTUSB pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
- if (pFontUSB == NULL) {
- return 0xFFFF;
- }
- FX_WORD wBitField = pFontUSB->wBitField;
- if (wBitField >= 128) {
- return 0xFFFF;
- }
- IFX_Font* pFont = NULL;
- m_FontMapper.Lookup((void*)(uintptr_t)wUnicode, (void*&)pFont);
- if (pFont != NULL && pFont != (IFX_Font*)this) {
- iGlyphIndex =
- ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
- if (iGlyphIndex != 0xFFFF) {
- int32_t i = m_SubstFonts.Find(pFont);
- if (i > -1) {
- iGlyphIndex |= ((i + 1) << 24);
- if (ppFont != NULL) {
- *ppFont = pFont;
- }
- return iGlyphIndex;
- }
- }
- }
- if (m_pFontMgr != NULL && bRecursive) {
- CFX_WideString wsFamily;
- GetFamilyName(wsFamily);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode(
- wUnicode, GetFontStyles(), (const FX_WCHAR*)wsFamily);
-#else
- IFX_Font* pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(),
- (const FX_WCHAR*)wsFamily);
- if (NULL == pFont) {
- pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), NULL);
- }
-#endif
- if (pFont != NULL) {
- if (pFont == (IFX_Font*)this) {
- pFont->Release();
- return 0xFFFF;
- }
- m_FontMapper.SetAt((void*)(uintptr_t)wUnicode, (void*)pFont);
- int32_t i = m_SubstFonts.GetSize();
- m_SubstFonts.Add(pFont);
- iGlyphIndex =
- ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
- if (iGlyphIndex != 0xFFFF) {
- iGlyphIndex |= ((i + 1) << 24);
- if (ppFont != NULL) {
- *ppFont = pFont;
- }
- return iGlyphIndex;
- }
- }
- }
- return 0xFFFF;
-}
-int32_t CFX_GEFont::GetAscent() const {
- return m_pFont->GetAscent();
-}
-int32_t CFX_GEFont::GetDescent() const {
- return m_pFont->GetDescent();
-}
-void CFX_GEFont::Reset() {
- Lock();
- int32_t iCount = m_SubstFonts.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
- ((CFX_GEFont*)pFont)->Reset();
- }
- if (m_pCharWidthMap != NULL) {
- m_pCharWidthMap->RemoveAll();
- }
- if (m_pBBoxMap != NULL) {
- m_pBBoxMap->RemoveAll();
- }
- if (m_pRectArray != NULL) {
- m_pRectArray->RemoveAll();
- }
- Unlock();
-}
-IFX_Font* CFX_GEFont::GetSubstFont(int32_t iGlyphIndex) const {
- iGlyphIndex = ((FX_DWORD)iGlyphIndex) >> 24;
- return iGlyphIndex == 0 ? (IFX_Font*)this
- : (IFX_Font*)m_SubstFonts[iGlyphIndex - 1];
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_gefont.h"
+#include "fx_fontutils.h"
+#ifndef _FXPLUS
+IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage,
+ IFX_FontMgr* pFontMgr) {
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
+ }
+ return NULL;
+#else
+ CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer,
+ int32_t iLength,
+ IFX_FontMgr* pFontMgr) {
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pBuffer, iLength, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pBuffer, iLength)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName,
+ IFX_FontMgr* pFontMgr) {
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pszFileName, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pszFileName)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream,
+ IFX_FontMgr* pFontMgr,
+ FX_BOOL bSaveStream) {
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pFontStream, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pFontStream, bSaveStream)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont,
+ IFX_FontMgr* pFontMgr,
+ FX_BOOL bTakeOver) {
+ CFX_GEFont* pFont = new CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pExtFont, bTakeOver)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+CFX_GEFont::CFX_GEFont(IFX_FontMgr* pFontMgr)
+ : CFX_ThreadLock(),
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ m_bUseLogFontStyle(FALSE),
+ m_dwLogFontStyle(0),
+#endif
+ m_pFont(NULL),
+ m_pFontMgr(pFontMgr),
+ m_iRefCount(1),
+ m_bExtFont(FALSE),
+ m_pStream(NULL),
+ m_pFileRead(NULL),
+ m_pFontEncoding(NULL),
+ m_pCharWidthMap(NULL),
+ m_pRectArray(NULL),
+ m_pBBoxMap(NULL),
+ m_pProvider(NULL),
+ m_wCharSet(0xFFFF),
+ m_SubstFonts(),
+ m_FontMapper(16) {
+}
+
+CFX_GEFont::CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles)
+ : CFX_ThreadLock(),
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ m_bUseLogFontStyle(FALSE),
+ m_dwLogFontStyle(0),
+#endif
+ m_pFont(NULL),
+ m_pFontMgr(src.m_pFontMgr),
+ m_iRefCount(1),
+ m_bExtFont(FALSE),
+ m_pStream(NULL),
+ m_pFileRead(NULL),
+ m_pFontEncoding(NULL),
+ m_pCharWidthMap(NULL),
+ m_pRectArray(NULL),
+ m_pBBoxMap(NULL),
+ m_pProvider(NULL),
+ m_wCharSet(0xFFFF),
+ m_SubstFonts(),
+ m_FontMapper(16) {
+ m_pFont = new CFX_Font;
+ FXSYS_assert(m_pFont != NULL);
+ FXSYS_assert(src.m_pFont != NULL);
+ m_pFont->LoadClone(src.m_pFont);
+ CFX_SubstFont* pSubst = m_pFont->GetSubstFont();
+ if (!pSubst) {
+ pSubst = new CFX_SubstFont;
+ m_pFont->SetSubstFont(pSubst);
+ }
+ pSubst->m_Weight =
+ (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC;
+ }
+ InitFont();
+}
+CFX_GEFont::~CFX_GEFont() {
+ int32_t iCount = m_SubstFonts.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
+ pFont->Release();
+ }
+ m_SubstFonts.RemoveAll();
+ m_FontMapper.RemoveAll();
+ if (m_pFileRead != NULL) {
+ m_pFileRead->Release();
+ }
+ if (m_pStream != NULL) {
+ m_pStream->Release();
+ }
+ if (m_pFontEncoding != NULL) {
+ delete m_pFontEncoding;
+ }
+ if (m_pCharWidthMap != NULL) {
+ delete m_pCharWidthMap;
+ }
+ if (m_pRectArray != NULL) {
+ delete m_pRectArray;
+ }
+ if (m_pBBoxMap != NULL) {
+ delete m_pBBoxMap;
+ }
+ if (m_pFont != NULL && !m_bExtFont) {
+ delete m_pFont;
+ }
+}
+void CFX_GEFont::Release() {
+ if (--m_iRefCount < 1) {
+ if (m_pFontMgr != NULL) {
+ m_pFontMgr->RemoveFont(this);
+ }
+ delete this;
+ }
+}
+IFX_Font* CFX_GEFont::Retain() {
+ ++m_iRefCount;
+ return this;
+}
+FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage) {
+ if (m_pFont) {
+ return FALSE;
+ }
+ Lock();
+ CFX_ByteString csFontFamily;
+ if (pszFontFamily != NULL) {
+ csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily);
+ }
+ FX_DWORD dwFlags = 0;
+ if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
+ dwFlags |= FXFONT_FIXED_PITCH;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ dwFlags |= FXFONT_SERIF;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ dwFlags |= FXFONT_SYMBOLIC;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ dwFlags |= FXFONT_SCRIPT;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ dwFlags |= FXFONT_ITALIC;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ dwFlags |= FXFONT_BOLD;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_ExactMatch) {
+ dwFlags |= FXFONT_EXACTMATCH;
+ }
+ int32_t iWeight =
+ (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
+ if (wCharSet == 0xFFFF) {
+ wCharSet = FXSYS_GetACP();
+ }
+ m_wCharSet = wCharSet;
+ m_pFont = new CFX_Font;
+ if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) {
+ csFontFamily += ",BoldItalic";
+ } else if (dwFlags & FXFONT_BOLD) {
+ csFontFamily += ",Bold";
+ } else if (dwFlags & FXFONT_ITALIC) {
+ csFontFamily += ",Italic";
+ }
+ m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage);
+ FX_BOOL bRet = m_pFont->GetFace() != nullptr;
+ if (bRet) {
+ bRet = InitFont();
+ }
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(const uint8_t* pBuffer, int32_t length) {
+ if (m_pFont) {
+ return FALSE;
+ }
+ Lock();
+ m_pFont = new CFX_Font;
+ FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length);
+ if (bRet) {
+ bRet = InitFont();
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFileName) {
+ if (m_pFont || m_pStream || m_pFileRead) {
+ return FALSE;
+ }
+ Lock();
+ m_pStream = IFX_Stream::CreateStream(
+ pszFileName, FX_STREAMACCESS_Binary | FX_STREAMACCESS_Read);
+ m_pFileRead = FX_CreateFileRead(m_pStream);
+ FX_BOOL bRet = FALSE;
+ if (m_pStream && m_pFileRead) {
+ m_pFont = new CFX_Font;
+ bRet = m_pFont->LoadFile(m_pFileRead);
+ if (bRet) {
+ bRet = InitFont();
+ } else {
+ m_pFileRead->Release();
+ m_pFileRead = nullptr;
+ }
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream) {
+ if (m_pFont || m_pFileRead || !pFontStream || pFontStream->GetLength() < 1) {
+ return FALSE;
+ }
+ Lock();
+ if (bSaveStream) {
+ m_pStream = pFontStream;
+ }
+ m_pFileRead = FX_CreateFileRead(pFontStream);
+ m_pFont = new CFX_Font;
+ FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead);
+ if (bRet) {
+ bRet = InitFont();
+ } else {
+ m_pFileRead->Release();
+ m_pFileRead = nullptr;
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver) {
+ if (m_pFont || !pExtFont) {
+ return FALSE;
+ }
+ Lock();
+ m_pFont = pExtFont;
+ FX_BOOL bRet = !!m_pFont;
+ if (bRet) {
+ m_bExtFont = !bTakeOver;
+ bRet = InitFont();
+ } else {
+ m_bExtFont = TRUE;
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::InitFont() {
+ if (!m_pFont) {
+ return FALSE;
+ }
+ if (!m_pFontEncoding) {
+ m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont);
+ if (!m_pFontEncoding) {
+ return FALSE;
+ }
+ }
+ if (!m_pCharWidthMap) {
+ m_pCharWidthMap = new CFX_WordDiscreteArray(1024);
+ }
+ if (!m_pRectArray) {
+ m_pRectArray = new CFX_RectMassArray(16);
+ }
+ if (!m_pBBoxMap) {
+ m_pBBoxMap = new CFX_MapPtrToPtr(16);
+ }
+ return TRUE;
+}
+IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage) {
+ if (GetFontStyles() == dwFontStyles) {
+ return Retain();
+ }
+ return new CFX_GEFont(*this, dwFontStyles);
+}
+uint8_t CFX_GEFont::GetCharSet() const {
+ if (m_wCharSet != 0xFFFF) {
+ return (uint8_t)m_wCharSet;
+ }
+ if (!m_pFont->GetSubstFont()) {
+ return FX_CHARSET_Default;
+ }
+ return m_pFont->GetSubstFont()->m_Charset;
+}
+void CFX_GEFont::GetFamilyName(CFX_WideString& wsFamily) const {
+ if (!m_pFont->GetSubstFont() ||
+ m_pFont->GetSubstFont()->m_Family.GetLength() == 0) {
+ wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName());
+ } else {
+ wsFamily = CFX_WideString::FromLocal(m_pFont->GetSubstFont()->m_Family);
+ }
+}
+void CFX_GEFont::GetPsName(CFX_WideString& wsName) const {
+ wsName = m_pFont->GetPsName();
+}
+FX_DWORD CFX_GEFont::GetFontStyles() const {
+ FXSYS_assert(m_pFont != NULL);
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (m_bUseLogFontStyle) {
+ return m_dwLogFontStyle;
+ }
+#endif
+ FX_DWORD dwStyles = 0;
+ if (!m_pFont->GetSubstFont()) {
+ if (m_pFont->IsBold()) {
+ dwStyles |= FX_FONTSTYLE_Bold;
+ }
+ if (m_pFont->IsItalic()) {
+ dwStyles |= FX_FONTSTYLE_Italic;
+ }
+ } else {
+ if (m_pFont->GetSubstFont()->m_Weight == FXFONT_FW_BOLD) {
+ dwStyles |= FX_FONTSTYLE_Bold;
+ }
+ if (m_pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_ITALIC) {
+ dwStyles |= FX_FONTSTYLE_Italic;
+ }
+ }
+ return dwStyles;
+}
+FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bCharCode) {
+ return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
+}
+FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode) {
+ FXSYS_assert(m_pCharWidthMap != NULL);
+ iWidth = m_pCharWidthMap->GetAt(wUnicode, 0);
+ if (iWidth < 1) {
+ if (!m_pProvider ||
+ !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) {
+ IFX_Font* pFont = NULL;
+ int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ iWidth = m_pFont->GetGlyphWidth(iGlyph);
+ if (iWidth < 0) {
+ iWidth = -1;
+ }
+ } else if (((CFX_GEFont*)pFont)
+ ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ } else {
+ iWidth = -1;
+ }
+ }
+ Lock();
+ m_pCharWidthMap->SetAtGrow(wUnicode, (int16_t)iWidth);
+ Unlock();
+ } else if (iWidth == 65535) {
+ iWidth = -1;
+ }
+ return iWidth > 0;
+}
+FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bCharCode) {
+ return GetCharBBox(wUnicode, bbox, TRUE, bCharCode);
+}
+FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode) {
+ FXSYS_assert(m_pRectArray != NULL);
+ FXSYS_assert(m_pBBoxMap != NULL);
+ void* pRect = NULL;
+ if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
+ IFX_Font* pFont = NULL;
+ int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ FX_RECT rtBBox;
+ if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
+ Lock();
+ CFX_Rect rt;
+ rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
+ int32_t index = m_pRectArray->Add(rt);
+ pRect = m_pRectArray->GetPtrAt(index);
+ m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
+ Unlock();
+ }
+ } else if (((CFX_GEFont*)pFont)
+ ->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ }
+ }
+ if (pRect == NULL) {
+ return FALSE;
+ }
+ bbox = *(FX_LPCRECT)pRect;
+ return TRUE;
+}
+FX_BOOL CFX_GEFont::GetBBox(CFX_Rect& bbox) {
+ FX_RECT rt(0, 0, 0, 0);
+ FX_BOOL bRet = m_pFont->GetBBox(rt);
+ if (bRet) {
+ bbox.left = rt.left;
+ bbox.width = rt.Width();
+ bbox.top = rt.bottom;
+ bbox.height = -rt.Height();
+ }
+ return bRet;
+}
+int32_t CFX_GEFont::GetItalicAngle() const {
+ if (!m_pFont->GetSubstFont()) {
+ return 0;
+ }
+ return m_pFont->GetSubstFont()->m_ItalicAngle;
+}
+int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) {
+ return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
+}
+int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode,
+ FX_BOOL bRecursive,
+ IFX_Font** ppFont,
+ FX_BOOL bCharCode) {
+ FXSYS_assert(m_pFontEncoding != NULL);
+ int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
+ if (iGlyphIndex > 0) {
+ if (ppFont != NULL) {
+ *ppFont = (IFX_Font*)this;
+ }
+ return iGlyphIndex;
+ }
+ FGAS_LPCFONTUSB pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
+ if (pFontUSB == NULL) {
+ return 0xFFFF;
+ }
+ FX_WORD wBitField = pFontUSB->wBitField;
+ if (wBitField >= 128) {
+ return 0xFFFF;
+ }
+ IFX_Font* pFont = NULL;
+ m_FontMapper.Lookup((void*)(uintptr_t)wUnicode, (void*&)pFont);
+ if (pFont != NULL && pFont != (IFX_Font*)this) {
+ iGlyphIndex =
+ ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyphIndex != 0xFFFF) {
+ int32_t i = m_SubstFonts.Find(pFont);
+ if (i > -1) {
+ iGlyphIndex |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyphIndex;
+ }
+ }
+ }
+ if (m_pFontMgr != NULL && bRecursive) {
+ CFX_WideString wsFamily;
+ GetFamilyName(wsFamily);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode(
+ wUnicode, GetFontStyles(), (const FX_WCHAR*)wsFamily);
+#else
+ IFX_Font* pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(),
+ (const FX_WCHAR*)wsFamily);
+ if (NULL == pFont) {
+ pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), NULL);
+ }
+#endif
+ if (pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ pFont->Release();
+ return 0xFFFF;
+ }
+ m_FontMapper.SetAt((void*)(uintptr_t)wUnicode, (void*)pFont);
+ int32_t i = m_SubstFonts.GetSize();
+ m_SubstFonts.Add(pFont);
+ iGlyphIndex =
+ ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyphIndex != 0xFFFF) {
+ iGlyphIndex |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyphIndex;
+ }
+ }
+ }
+ return 0xFFFF;
+}
+int32_t CFX_GEFont::GetAscent() const {
+ return m_pFont->GetAscent();
+}
+int32_t CFX_GEFont::GetDescent() const {
+ return m_pFont->GetDescent();
+}
+void CFX_GEFont::Reset() {
+ Lock();
+ int32_t iCount = m_SubstFonts.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i];
+ ((CFX_GEFont*)pFont)->Reset();
+ }
+ if (m_pCharWidthMap != NULL) {
+ m_pCharWidthMap->RemoveAll();
+ }
+ if (m_pBBoxMap != NULL) {
+ m_pBBoxMap->RemoveAll();
+ }
+ if (m_pRectArray != NULL) {
+ m_pRectArray->RemoveAll();
+ }
+ Unlock();
+}
+IFX_Font* CFX_GEFont::GetSubstFont(int32_t iGlyphIndex) const {
+ iGlyphIndex = ((FX_DWORD)iGlyphIndex) >> 24;
+ return iGlyphIndex == 0 ? (IFX_Font*)this
+ : (IFX_Font*)m_SubstFonts[iGlyphIndex - 1];
+}
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gefont.h b/xfa/src/fgas/src/font/fx_gefont.h
index a85cffa5e5..9137cba82d 100644
--- a/xfa/src/fgas/src/font/fx_gefont.h
+++ b/xfa/src/fgas/src/font/fx_gefont.h
@@ -1,90 +1,90 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_GRAPHOBJS_IMP
-#define _FX_GRAPHOBJS_IMP
-#ifndef _FXPLUS
-class CFX_GEFontMgr;
-#ifndef FXFONT_SUBST_ITALIC
-#define FXFONT_SUBST_ITALIC 0x02
-#endif
-class CFX_GEFont : public IFX_Font, public CFX_ThreadLock {
- public:
- CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles);
- CFX_GEFont(IFX_FontMgr* pFontMgr);
- ~CFX_GEFont();
- virtual void Release();
- virtual IFX_Font* Retain();
- FX_BOOL LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage);
- FX_BOOL LoadFont(const uint8_t* pBuffer, int32_t length);
- FX_BOOL LoadFont(const FX_WCHAR* pszFileName);
- FX_BOOL LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream);
- FX_BOOL LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver = FALSE);
- virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0);
- virtual void GetFamilyName(CFX_WideString& wsFamily) const;
- virtual void GetPsName(CFX_WideString& wsName) const;
- virtual FX_DWORD GetFontStyles() const;
- virtual uint8_t GetCharSet() const;
- virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bCharCode = FALSE);
- virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
- virtual int32_t GetAscent() const;
- virtual int32_t GetDescent() const;
- virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bCharCode = FALSE);
- virtual FX_BOOL GetBBox(CFX_Rect& bbox);
- virtual int32_t GetItalicAngle() const;
- virtual void Reset();
- virtual IFX_Font* GetSubstFont(int32_t iGlyphIndex) const;
- virtual void* GetDevFont() const { return (void*)m_pFont; }
- virtual void SetFontProvider(IFX_FontProvider* pProvider) {
- m_pProvider = pProvider;
- }
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- virtual void SetLogicalFontStyle(FX_DWORD dwLogFontStyle) {
- m_bUseLogFontStyle = TRUE;
- m_dwLogFontStyle = dwLogFontStyle;
- };
-#endif
- protected:
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
- FX_BOOL m_bUseLogFontStyle;
- FX_DWORD m_dwLogFontStyle;
-#endif
- CFX_Font* m_pFont;
- IFX_FontMgr* m_pFontMgr;
- int32_t m_iRefCount;
- FX_BOOL m_bExtFont;
- IFX_Stream* m_pStream;
- IFX_FileRead* m_pFileRead;
- CFX_UnicodeEncoding* m_pFontEncoding;
- CFX_WordDiscreteArray* m_pCharWidthMap;
- CFX_RectMassArray* m_pRectArray;
- CFX_MapPtrToPtr* m_pBBoxMap;
- IFX_FontProvider* m_pProvider;
- FX_WORD m_wCharSet;
- CFX_PtrArray m_SubstFonts;
- CFX_MapPtrToPtr m_FontMapper;
- FX_BOOL InitFont();
- FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
- CFX_Rect& bbox,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode = FALSE);
- FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
- int32_t& iWidth,
- FX_BOOL bRecursive,
- FX_BOOL bCharCode = FALSE);
- int32_t GetGlyphIndex(FX_WCHAR wUnicode,
- FX_BOOL bRecursive,
- IFX_Font** ppFont,
- FX_BOOL bCharCode = FALSE);
-};
-#endif
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_GRAPHOBJS_IMP
+#define _FX_GRAPHOBJS_IMP
+#ifndef _FXPLUS
+class CFX_GEFontMgr;
+#ifndef FXFONT_SUBST_ITALIC
+#define FXFONT_SUBST_ITALIC 0x02
+#endif
+class CFX_GEFont : public IFX_Font, public CFX_ThreadLock {
+ public:
+ CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles);
+ CFX_GEFont(IFX_FontMgr* pFontMgr);
+ ~CFX_GEFont();
+ virtual void Release();
+ virtual IFX_Font* Retain();
+ FX_BOOL LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage);
+ FX_BOOL LoadFont(const uint8_t* pBuffer, int32_t length);
+ FX_BOOL LoadFont(const FX_WCHAR* pszFileName);
+ FX_BOOL LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream);
+ FX_BOOL LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver = FALSE);
+ virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0);
+ virtual void GetFamilyName(CFX_WideString& wsFamily) const;
+ virtual void GetPsName(CFX_WideString& wsName) const;
+ virtual FX_DWORD GetFontStyles() const;
+ virtual uint8_t GetCharSet() const;
+ virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bCharCode = FALSE);
+ virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
+ virtual int32_t GetAscent() const;
+ virtual int32_t GetDescent() const;
+ virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bCharCode = FALSE);
+ virtual FX_BOOL GetBBox(CFX_Rect& bbox);
+ virtual int32_t GetItalicAngle() const;
+ virtual void Reset();
+ virtual IFX_Font* GetSubstFont(int32_t iGlyphIndex) const;
+ virtual void* GetDevFont() const { return (void*)m_pFont; }
+ virtual void SetFontProvider(IFX_FontProvider* pProvider) {
+ m_pProvider = pProvider;
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ virtual void SetLogicalFontStyle(FX_DWORD dwLogFontStyle) {
+ m_bUseLogFontStyle = TRUE;
+ m_dwLogFontStyle = dwLogFontStyle;
+ };
+#endif
+ protected:
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FX_BOOL m_bUseLogFontStyle;
+ FX_DWORD m_dwLogFontStyle;
+#endif
+ CFX_Font* m_pFont;
+ IFX_FontMgr* m_pFontMgr;
+ int32_t m_iRefCount;
+ FX_BOOL m_bExtFont;
+ IFX_Stream* m_pStream;
+ IFX_FileRead* m_pFileRead;
+ CFX_UnicodeEncoding* m_pFontEncoding;
+ CFX_WordDiscreteArray* m_pCharWidthMap;
+ CFX_RectMassArray* m_pRectArray;
+ CFX_MapPtrToPtr* m_pBBoxMap;
+ IFX_FontProvider* m_pProvider;
+ FX_WORD m_wCharSet;
+ CFX_PtrArray m_SubstFonts;
+ CFX_MapPtrToPtr m_FontMapper;
+ FX_BOOL InitFont();
+ FX_BOOL GetCharBBox(FX_WCHAR wUnicode,
+ CFX_Rect& bbox,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode = FALSE);
+ FX_BOOL GetCharWidth(FX_WCHAR wUnicode,
+ int32_t& iWidth,
+ FX_BOOL bRecursive,
+ FX_BOOL bCharCode = FALSE);
+ int32_t GetGlyphIndex(FX_WCHAR wUnicode,
+ FX_BOOL bRecursive,
+ IFX_Font** ppFont,
+ FX_BOOL bCharCode = FALSE);
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.cpp b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp
index 5053a087e1..e8b8f49d59 100644
--- a/xfa/src/fgas/src/font/fx_stdfontmgr.cpp
+++ b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp
@@ -1,1527 +1,1527 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/src/fxcrt/extension.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_stdfontmgr.h"
-#include "fx_fontutils.h"
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-IFX_FontMgr* IFX_FontMgr::Create(FX_LPEnumAllFonts pEnumerator,
- FX_LPMatchFont pMatcher,
- void* pUserData) {
- return new CFX_StdFontMgrImp(pEnumerator, pMatcher, pUserData);
-}
-CFX_StdFontMgrImp::CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator,
- FX_LPMatchFont pMatcher,
- void* pUserData)
- : m_pMatcher(pMatcher),
- m_pEnumerator(pEnumerator),
- m_FontFaces(),
- m_Fonts(),
- m_CPFonts(8),
- m_FamilyFonts(16),
- m_UnicodeFonts(16),
- m_BufferFonts(4),
- m_FileFonts(4),
- m_StreamFonts(4),
- m_DeriveFonts(4),
- m_pUserData(pUserData) {
- if (m_pEnumerator != NULL) {
- m_pEnumerator(m_FontFaces, m_pUserData, NULL, 0xFEFF);
- }
- if (m_pMatcher == NULL) {
- m_pMatcher = FX_DefFontMatcher;
- }
- FXSYS_assert(m_pMatcher != NULL);
-}
-CFX_StdFontMgrImp::~CFX_StdFontMgrImp() {
- m_FontFaces.RemoveAll();
- m_CPFonts.RemoveAll();
- m_FamilyFonts.RemoveAll();
- m_UnicodeFonts.RemoveAll();
- m_BufferFonts.RemoveAll();
- m_FileFonts.RemoveAll();
- m_StreamFonts.RemoveAll();
- m_DeriveFonts.RemoveAll();
- for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--) {
- IFX_Font* pFont = (IFX_Font*)m_Fonts[i];
- if (pFont != NULL) {
- pFont->Release();
- }
- }
- m_Fonts.RemoveAll();
-}
-IFX_Font* CFX_StdFontMgrImp::GetDefFontByCodePage(
- FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- FX_DWORD dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
- IFX_Font* pFont = NULL;
- if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
- return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
- }
- FX_LPCFONTDESCRIPTOR pFD;
- if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
- if ((pFD = FindFont(NULL, dwFontStyles, TRUE, wCodePage)) == NULL)
- if ((pFD = FindFont(NULL, dwFontStyles, FALSE, wCodePage)) == NULL) {
- return NULL;
- }
- FXSYS_assert(pFD != NULL);
- pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
- m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- return LoadFont(pFont, dwFontStyles, wCodePage);
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::GetDefFontByCharset(
- uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return GetDefFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
- pszFontFamily);
-}
-#define _FX_USEGASFONTMGR_
-IFX_Font* CFX_StdFontMgrImp::GetDefFontByUnicode(
- FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- FGAS_LPCFONTUSB pRet = FGAS_GetUnicodeBitField(wUnicode);
- if (pRet->wBitField == 999) {
- return NULL;
- }
- FX_DWORD dwHash =
- FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
- IFX_Font* pFont = NULL;
- if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
- return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : NULL;
- }
-#ifdef _FX_USEGASFONTMGR_
- FX_LPCFONTDESCRIPTOR pFD =
- FindFont(pszFontFamily, dwFontStyles, FALSE, pRet->wCodePage,
- pRet->wBitField, wUnicode);
- if (pFD == NULL && pszFontFamily) {
- pFD = FindFont(NULL, dwFontStyles, FALSE, pRet->wCodePage, pRet->wBitField,
- wUnicode);
- }
- if (pFD == NULL) {
- return NULL;
- }
- FXSYS_assert(pFD);
- FX_WORD wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
- const FX_WCHAR* pFontFace = pFD->wsFontFace;
- pFont = IFX_Font::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
-#else
- CFX_FontMapper* pBuiltinMapper =
- CFX_GEModule::Get()->GetFontMgr()->m_pBuiltinMapper;
- if (pBuiltinMapper == NULL) {
- return NULL;
- }
- int32_t iWeight =
- (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
- int italic_angle = 0;
- FXFT_Face ftFace = pBuiltinMapper->FindSubstFontByUnicode(
- wUnicode, dwFontStyles, iWeight, italic_angle);
- if (ftFace == NULL) {
- return NULL;
- }
- CFX_Font* pFXFont = new CFX_Font;
- pFXFont->m_Face = ftFace;
- pFXFont->m_pFontData = FXFT_Get_Face_Stream_Base(ftFace);
- pFXFont->m_dwSize = FXFT_Get_Face_Stream_Size(ftFace);
- pFont = IFX_Font::LoadFont(pFXFont, this);
- FX_WORD wCodePage = pRet->wCodePage;
- CFX_WideString wsPsName = pFXFont->GetPsName();
- const FX_WCHAR* pFontFace = wsPsName;
-#endif
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
- m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
- m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- return LoadFont(pFont, dwFontStyles, wCodePage);
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::GetDefFontByLanguage(
- FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return GetDefFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage),
- dwFontStyles, pszFontFamily);
-}
-IFX_Font* CFX_StdFontMgrImp::LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage) {
- FX_DWORD dwHash =
- FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
- IFX_Font* pFont = NULL;
- if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
- return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
- }
- FX_LPCFONTDESCRIPTOR pFD = NULL;
- if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
- if ((pFD = FindFont(pszFontFamily, dwFontStyles, FALSE, wCodePage)) ==
- NULL) {
- return NULL;
- }
- FXSYS_assert(pFD != NULL);
- if (wCodePage == 0xFFFF) {
- wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
- }
- pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
- m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- return LoadFont(pFont, dwFontStyles, wCodePage);
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::LoadFont(const uint8_t* pBuffer, int32_t iLength) {
- FXSYS_assert(pBuffer != NULL && iLength > 0);
- IFX_Font* pFont = NULL;
- if (m_BufferFonts.Lookup((void*)pBuffer, (void*&)pFont)) {
- if (pFont != NULL) {
- return pFont->Retain();
- }
- }
- pFont = IFX_Font::LoadFont(pBuffer, iLength, this);
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_BufferFonts.SetAt((void*)pBuffer, pFont);
- return pFont->Retain();
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::LoadFont(const FX_WCHAR* pszFileName) {
- FXSYS_assert(pszFileName != NULL);
- FX_DWORD dwHash = FX_HashCode_String_GetW(pszFileName, -1);
- IFX_Font* pFont = NULL;
- if (m_FileFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
- if (pFont != NULL) {
- return pFont->Retain();
- }
- }
- pFont = IFX_Font::LoadFont(pszFileName, NULL);
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_FileFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- return pFont->Retain();
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Stream* pFontStream,
- const FX_WCHAR* pszFontAlias,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage,
- FX_BOOL bSaveStream) {
- FXSYS_assert(pFontStream != NULL && pFontStream->GetLength() > 0);
- IFX_Font* pFont = NULL;
- if (m_StreamFonts.Lookup((void*)pFontStream, (void*&)pFont)) {
- if (pFont != NULL) {
- if (pszFontAlias != NULL) {
- FX_DWORD dwHash =
- FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
- m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- }
- return LoadFont(pFont, dwFontStyles, wCodePage);
- }
- }
- pFont = IFX_Font::LoadFont(pFontStream, this, bSaveStream);
- if (pFont != NULL) {
- m_Fonts.Add(pFont);
- m_StreamFonts.SetAt((void*)pFontStream, (void*)pFont);
- if (pszFontAlias != NULL) {
- FX_DWORD dwHash =
- FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
- m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- }
- return LoadFont(pFont, dwFontStyles, wCodePage);
- }
- return NULL;
-}
-IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Font* pSrcFont,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage) {
- FXSYS_assert(pSrcFont != NULL);
- if (pSrcFont->GetFontStyles() == dwFontStyles) {
- return pSrcFont->Retain();
- }
- void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles,
- (void*)(uintptr_t)wCodePage};
- FX_DWORD dwHash =
- FX_HashCode_String_GetA((const FX_CHAR*)buffer, 3 * sizeof(void*));
- IFX_Font* pFont = NULL;
- if (m_DeriveFonts.GetCount() > 0) {
- m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont);
- if (pFont != NULL) {
- return pFont->Retain();
- }
- }
- pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
- if (pFont != NULL) {
- m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
- int32_t index = m_Fonts.Find(pFont);
- if (index < 0) {
- m_Fonts.Add(pFont);
- pFont->Retain();
- }
- return pFont;
- }
- return NULL;
-}
-void CFX_StdFontMgrImp::ClearFontCache() {
- int32_t iCount = m_Fonts.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- IFX_Font* pFont = (IFX_Font*)m_Fonts[i];
- if (pFont != NULL) {
- pFont->Reset();
- }
- }
-}
-void CFX_StdFontMgrImp::RemoveFont(CFX_MapPtrToPtr& fontMap, IFX_Font* pFont) {
- FX_POSITION pos = fontMap.GetStartPosition();
- void* pKey;
- void* pFind;
- while (pos != NULL) {
- pFind = NULL;
- fontMap.GetNextAssoc(pos, pKey, pFind);
- if (pFind != (void*)pFont) {
- continue;
- }
- fontMap.RemoveKey(pKey);
- break;
- }
-}
-void CFX_StdFontMgrImp::RemoveFont(IFX_Font* pFont) {
- RemoveFont(m_CPFonts, pFont);
- RemoveFont(m_FamilyFonts, pFont);
- RemoveFont(m_UnicodeFonts, pFont);
- RemoveFont(m_BufferFonts, pFont);
- RemoveFont(m_FileFonts, pFont);
- RemoveFont(m_StreamFonts, pFont);
- RemoveFont(m_DeriveFonts, pFont);
- int32_t iFind = m_Fonts.Find(pFont);
- if (iFind > -1) {
- m_Fonts.RemoveAt(iFind, 1);
- }
-}
-FX_LPCFONTDESCRIPTOR CFX_StdFontMgrImp::FindFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_DWORD dwMatchFlags,
- FX_WORD wCodePage,
- FX_DWORD dwUSB,
- FX_WCHAR wUnicode) {
- if (m_pMatcher == NULL) {
- return NULL;
- }
- FX_FONTMATCHPARAMS params;
- FX_memset(&params, 0, sizeof(params));
- params.dwUSB = dwUSB;
- params.wUnicode = wUnicode;
- params.wCodePage = wCodePage;
- params.pwsFamily = pszFontFamily;
- params.dwFontStyles = dwFontStyles;
- params.dwMatchFlags = dwMatchFlags;
- FX_LPCFONTDESCRIPTOR pDesc = m_pMatcher(&params, m_FontFaces, m_pUserData);
- if (pDesc) {
- return pDesc;
- }
- if (pszFontFamily && m_pEnumerator) {
- CFX_FontDescriptors namedFonts;
- m_pEnumerator(namedFonts, m_pUserData, pszFontFamily, wUnicode);
- params.pwsFamily = NULL;
- pDesc = m_pMatcher(&params, namedFonts, m_pUserData);
- if (pDesc == NULL) {
- return NULL;
- }
- for (int32_t i = m_FontFaces.GetSize() - 1; i >= 0; i--) {
- FX_LPCFONTDESCRIPTOR pMatch = m_FontFaces.GetPtrAt(i);
- if (*pMatch == *pDesc) {
- return pMatch;
- }
- }
- int index = m_FontFaces.Add(*pDesc);
- return m_FontFaces.GetPtrAt(index);
- }
- return NULL;
-}
-FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams,
- const CFX_FontDescriptors& fonts,
- void* pUserData) {
- FX_LPCFONTDESCRIPTOR pBestFont = NULL;
- int32_t iBestSimilar = 0;
- FX_BOOL bMatchStyle =
- (pParams->dwMatchFlags & FX_FONTMATCHPARA_MacthStyle) > 0;
- int32_t iCount = fonts.GetSize();
- for (int32_t i = 0; i < iCount; ++i) {
- FX_LPCFONTDESCRIPTOR pFont = fonts.GetPtrAt(i);
- if ((pFont->dwFontStyles & FX_FONTSTYLE_BoldItalic) ==
- FX_FONTSTYLE_BoldItalic) {
- continue;
- }
- if (pParams->pwsFamily) {
- if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace)) {
- continue;
- }
- if (pFont->uCharSet == FX_CHARSET_Symbol) {
- return pFont;
- }
- }
- if (pFont->uCharSet == FX_CHARSET_Symbol) {
- continue;
- }
- if (pParams->wCodePage != 0xFFFF) {
- if (FX_GetCodePageFromCharset(pFont->uCharSet) != pParams->wCodePage) {
- continue;
- }
- } else {
- if (pParams->dwUSB < 128) {
- FX_DWORD dwByte = pParams->dwUSB / 32;
- FX_DWORD dwUSB = 1 << (pParams->dwUSB % 32);
- if ((pFont->FontSignature.fsUsb[dwByte] & dwUSB) == 0) {
- continue;
- }
- }
- }
- if (bMatchStyle) {
- if ((pFont->dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F)) {
- return pFont;
- } else {
- continue;
- }
- }
- if (pParams->pwsFamily != NULL) {
- if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace) == 0) {
- return pFont;
- }
- }
- int32_t iSimilarValue = FX_GetSimilarValue(pFont, pParams->dwFontStyles);
- if (iBestSimilar < iSimilarValue) {
- iBestSimilar = iSimilarValue;
- pBestFont = pFont;
- }
- }
- return iBestSimilar < 1 ? NULL : pBestFont;
-}
-int32_t FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles) {
- int32_t iValue = 0;
- if ((dwFontStyles & FX_FONTSTYLE_Symbolic) ==
- (pFont->dwFontStyles & FX_FONTSTYLE_Symbolic)) {
- iValue += 64;
- }
- if ((dwFontStyles & FX_FONTSTYLE_FixedPitch) ==
- (pFont->dwFontStyles & FX_FONTSTYLE_FixedPitch)) {
- iValue += 32;
- }
- if ((dwFontStyles & FX_FONTSTYLE_Serif) ==
- (pFont->dwFontStyles & FX_FONTSTYLE_Serif)) {
- iValue += 16;
- }
- if ((dwFontStyles & FX_FONTSTYLE_Script) ==
- (pFont->dwFontStyles & FX_FONTSTYLE_Script)) {
- iValue += 8;
- }
- return iValue;
-}
-FX_LPMatchFont FX_GetDefFontMatchor() {
- return FX_DefFontMatcher;
-}
-FX_DWORD FX_GetGdiFontStyles(const LOGFONTW& lf) {
- FX_DWORD dwStyles = 0;
- if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH) {
- dwStyles |= FX_FONTSTYLE_FixedPitch;
- }
- uint8_t nFamilies = lf.lfPitchAndFamily & 0xF0;
- if (nFamilies == FF_ROMAN) {
- dwStyles |= FX_FONTSTYLE_Serif;
- }
- if (nFamilies == FF_SCRIPT) {
- dwStyles |= FX_FONTSTYLE_Script;
- }
- if (lf.lfCharSet == SYMBOL_CHARSET) {
- dwStyles |= FX_FONTSTYLE_Symbolic;
- }
- return dwStyles;
-}
-static int32_t CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX* lpelfe,
- NEWTEXTMETRICEX* lpntme,
- DWORD dwFontType,
- LPARAM lParam) {
- if (dwFontType != TRUETYPE_FONTTYPE) {
- return 1;
- }
- const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
- if (lf.lfFaceName[0] == L'@') {
- return 1;
- }
- FX_LPFONTDESCRIPTOR pFont = FX_Alloc(FX_FONTDESCRIPTOR, 1);
- FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR));
- pFont->uCharSet = lf.lfCharSet;
- pFont->dwFontStyles = FX_GetGdiFontStyles(lf);
- FXSYS_wcsncpy(pFont->wsFontFace, (const FX_WCHAR*)lf.lfFaceName, 31);
- pFont->wsFontFace[31] = 0;
- FX_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig,
- sizeof(lpntme->ntmFontSig));
- ((CFX_FontDescriptors*)lParam)->Add(*pFont);
- FX_Free(pFont);
- return 1;
-}
-static void FX_EnumGdiFonts(CFX_FontDescriptors& fonts,
- void* pUserData,
- const FX_WCHAR* pwsFaceName,
- FX_WCHAR wUnicode) {
- HDC hDC = ::GetDC(NULL);
- LOGFONTW lfFind;
- FX_memset(&lfFind, 0, sizeof(lfFind));
- lfFind.lfCharSet = DEFAULT_CHARSET;
- if (pwsFaceName) {
- FXSYS_wcsncpy((FX_WCHAR*)lfFind.lfFaceName, pwsFaceName, 31);
- lfFind.lfFaceName[31] = 0;
- }
- EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind,
- (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)&fonts, 0);
- ::ReleaseDC(NULL, hDC);
-}
-FX_LPEnumAllFonts FX_GetDefFontEnumerator() {
- return FX_EnumGdiFonts;
-}
-#else
-const FX_CHAR* g_FontFolders[] = {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
- "/usr/share/fonts", "/usr/share/X11/fonts/Type1",
- "/usr/share/X11/fonts/TTF", "/usr/local/share/fonts",
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts",
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
- "/system/fonts",
-#endif
-};
-CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
- for (int32_t i = 0; i < sizeof(g_FontFolders) / sizeof(const FX_CHAR*); i++) {
- m_FolderPaths.Add(g_FontFolders[i]);
- }
-}
-CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() {
-Restart:
- void* pCurHandle =
- m_FolderQueue.GetSize() == 0
- ? NULL
- : m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
- if (NULL == pCurHandle) {
- if (m_FolderPaths.GetSize() < 1) {
- return "";
- }
- pCurHandle = FX_OpenFolder(m_FolderPaths[m_FolderPaths.GetSize() - 1]);
- FX_HandleParentPath hpp;
- hpp.pFileHandle = pCurHandle;
- hpp.bsParentPath = m_FolderPaths[m_FolderPaths.GetSize() - 1];
- m_FolderQueue.Add(hpp);
- }
- CFX_ByteString bsName;
- FX_BOOL bFolder;
- CFX_ByteString bsFolderSpearator =
- CFX_ByteString::FromUnicode(CFX_WideString(FX_GetFolderSeparator()));
- while (TRUE) {
- if (!FX_GetNextFile(pCurHandle, bsName, bFolder)) {
- FX_CloseFolder(pCurHandle);
- m_FolderQueue.RemoveAt(m_FolderQueue.GetSize() - 1);
- if (m_FolderQueue.GetSize() == 0) {
- m_FolderPaths.RemoveAt(m_FolderPaths.GetSize() - 1);
- if (m_FolderPaths.GetSize() == 0) {
- return "";
- } else {
- goto Restart;
- }
- }
- pCurHandle =
- m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
- continue;
- }
- if (bsName == "." || bsName == "..") {
- continue;
- }
- if (bFolder) {
- FX_HandleParentPath hpp;
- hpp.bsParentPath =
- m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
- bsFolderSpearator + bsName;
- hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath);
- if (hpp.pFileHandle == NULL) {
- continue;
- }
- m_FolderQueue.Add(hpp);
- pCurHandle = hpp.pFileHandle;
- continue;
- }
- bsName =
- m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
- bsFolderSpearator + bsName;
- break;
- }
- return bsName;
-}
-FX_POSITION CFX_FontSourceEnum_File::GetStartPosition(void* pUserData) {
- m_wsNext = GetNextFile().UTF8Decode();
- if (0 == m_wsNext.GetLength()) {
- return (FX_POSITION)0;
- }
- return (FX_POSITION)-1;
-}
-IFX_FileAccess* CFX_FontSourceEnum_File::GetNext(FX_POSITION& pos,
- void* pUserData) {
- IFX_FileAccess* pAccess = FX_CreateDefaultFileAccess(m_wsNext);
- m_wsNext = GetNextFile().UTF8Decode();
- pos = 0 != m_wsNext.GetLength() ? pAccess : NULL;
- return (IFX_FileAccess*)pAccess;
-}
-IFX_FontSourceEnum* FX_CreateDefaultFontSourceEnum() {
- return (IFX_FontSourceEnum*)new CFX_FontSourceEnum_File;
-}
-IFX_FontMgr* IFX_FontMgr::Create(IFX_FontSourceEnum* pFontEnum,
- IFX_FontMgrDelegate* pDelegate,
- void* pUserData) {
- if (NULL == pFontEnum) {
- return NULL;
- }
- CFX_FontMgrImp* pFontMgr =
- new CFX_FontMgrImp(pFontEnum, pDelegate, pUserData);
- if (pFontMgr->EnumFonts()) {
- return pFontMgr;
- }
- delete pFontMgr;
- return NULL;
-}
-CFX_FontMgrImp::CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum,
- IFX_FontMgrDelegate* pDelegate,
- void* pUserData)
- : m_pFontSource(pFontEnum),
- m_pDelegate(pDelegate),
- m_pUserData(pUserData) {}
-
-FX_BOOL CFX_FontMgrImp::EnumFontsFromFontMapper() {
- CFX_FontMapper* pFontMapper =
- CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
- if (!pFontMapper)
- return FALSE;
- IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
- if (!pSystemFontInfo)
- return FALSE;
- pSystemFontInfo->EnumFontList(pFontMapper);
- for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
- IFX_FileRead* pFontStream =
- CreateFontStream(pFontMapper, pSystemFontInfo, i);
- if (!pFontStream)
- continue;
- ReportFaces(pFontStream);
- pFontStream->Release();
- }
- if (m_InstalledFonts.GetSize() == 0)
- return FALSE;
- return TRUE;
-}
-FX_BOOL CFX_FontMgrImp::EnumFontsFromFiles() {
- CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
- FX_POSITION pos = m_pFontSource->GetStartPosition();
- IFX_FileAccess* pFontSource = nullptr;
- IFX_FileRead* pFontStream = nullptr;
- while (pos) {
- pFontSource = m_pFontSource->GetNext(pos);
- pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
- if (!pFontStream) {
- pFontSource->Release();
- continue;
- }
- ReportFaces(pFontStream);
- pFontStream->Release();
- pFontSource->Release();
- }
- if (m_InstalledFonts.GetSize() == 0)
- return FALSE;
- return TRUE;
-}
-FX_BOOL CFX_FontMgrImp::EnumFonts() {
- if (EnumFontsFromFontMapper())
- return TRUE;
- return EnumFontsFromFiles();
-}
-void CFX_FontMgrImp::Release() {
- for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) {
- delete m_InstalledFonts[i];
- }
- FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- CFX_FontDescriptorInfos* pDescs;
- m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
- if (NULL != pDescs) {
- delete pDescs;
- }
- }
- pos = m_Hash2Fonts.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- CFX_ArrayTemplate<IFX_Font*>* pFonts;
- m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
- if (NULL != pFonts) {
- delete pFonts;
- }
- }
- m_Hash2Fonts.RemoveAll();
- pos = m_Hash2FileAccess.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- IFX_FileAccess* pFileAccess;
- m_Hash2FileAccess.GetNextAssoc(pos, dwHash, pFileAccess);
- if (NULL != pFileAccess) {
- pFileAccess->Release();
- }
- }
- pos = m_FileAccess2IFXFont.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- IFX_Font* pFont;
- m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
- if (NULL != pFont) {
- pFont->Release();
- }
- }
- pos = m_IFXFont2FileRead.GetStartPosition();
- while (pos) {
- IFX_Font* pFont;
- IFX_FileRead* pFileRead;
- m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
- pFileRead->Release();
- }
- delete this;
-}
-IFX_Font* CFX_FontMgrImp::GetDefFontByCodePage(FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCodePage(
- this, wCodePage, dwFontStyles,
- pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::GetDefFontByCharset(uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return NULL == m_pDelegate ? NULL
- : m_pDelegate->GetDefFontByCharset(
- this, nCharset, dwFontStyles, pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::GetDefFontByUnicode(FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return NULL == m_pDelegate ? NULL
- : m_pDelegate->GetDefFontByUnicode(
- this, wUnicode, dwFontStyles, pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::GetDefFontByLanguage(FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByLanguage(
- this, wLanguage, dwFontStyles,
- pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::GetFontByCodePage(FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- CFX_ByteString bsHash;
- bsHash.Format("%d, %d", wCodePage, dwFontStyles);
- bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
- FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
- CFX_ArrayTemplate<IFX_Font*>* pFonts = NULL;
- IFX_Font* pFont = NULL;
- if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
- if (NULL == pFonts) {
- return NULL;
- }
- if (0 != pFonts->GetSize()) {
- return pFonts->GetAt(0)->Retain();
- }
- }
- if (!pFonts)
- pFonts = new CFX_ArrayTemplate<IFX_Font*>;
- m_Hash2Fonts.SetAt(dwHash, pFonts);
- CFX_FontDescriptorInfos* sortedFonts = NULL;
- if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
- sortedFonts = new CFX_FontDescriptorInfos;
- MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
- CFX_WideString(pszFontFamily), 0);
- m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
- }
- if (sortedFonts->GetSize() == 0) {
- return NULL;
- }
- CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
- if (pDesc->m_pFileAccess)
- pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, nullptr);
- else
- pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
- if (NULL != pFont) {
- pFont->SetLogicalFontStyle(dwFontStyles);
- }
- pFonts->Add(pFont);
- return pFont;
-}
-IFX_Font* CFX_FontMgrImp::GetFontByCharset(uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return GetFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
- pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::GetFontByUnicode(FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- IFX_Font* pFont = nullptr;
- if (m_FailedUnicodes2NULL.Lookup(wUnicode, pFont))
- return nullptr;
- FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wUnicode);
- FX_WORD wCodePage = x ? x->wCodePage : 0xFFFF;
- FX_WORD wBitField = x ? x->wBitField : 0x03E7;
- CFX_ByteString bsHash;
- if (wCodePage == 0xFFFF)
- bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
- else
- bsHash.Format("%d, %d", wCodePage, dwFontStyles);
- bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
- FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
- CFX_ArrayTemplate<IFX_Font*>* pFonts = nullptr;
- if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
- if (!pFonts)
- return nullptr;
- for (int32_t i = 0; i < pFonts->GetSize(); ++i) {
- if (VerifyUnicode(pFonts->GetAt(i), wUnicode))
- return pFonts->GetAt(i)->Retain();
- }
- }
- if (!pFonts)
- pFonts = new CFX_ArrayTemplate<IFX_Font*>;
- m_Hash2Fonts.SetAt(dwHash, pFonts);
- CFX_FontDescriptorInfos* sortedFonts = nullptr;
- if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
- sortedFonts = new CFX_FontDescriptorInfos;
- MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
- CFX_WideString(pszFontFamily), wUnicode);
- m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
- }
- for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) {
- CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
- if (!VerifyUnicode(pDesc, wUnicode))
- continue;
- if (pDesc->m_pFileAccess)
- pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, nullptr);
- else
- pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
- if (!pFont)
- continue;
- pFont->SetLogicalFontStyle(dwFontStyles);
- pFonts->Add(pFont);
- return pFont;
- }
- if (!pszFontFamily)
- m_FailedUnicodes2NULL.SetAt(wUnicode, nullptr);
- return nullptr;
-}
-FX_BOOL CFX_FontMgrImp::VerifyUnicode(CFX_FontDescriptor* pDesc,
- FX_WCHAR wcUnicode) {
- IFX_FileRead* pFileRead = nullptr;
- if (pDesc->m_pFileAccess)
- pFileRead = pDesc->m_pFileAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
- else
- pFileRead = CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
- if (!pFileRead)
- return FALSE;
- FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
- FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
- FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
- pFileRead->Release();
- if (!pFace)
- return FALSE;
- if (FXFT_Get_Face_External_Stream(pFace))
- FXFT_Clear_Face_External_Stream(pFace);
- FXFT_Done_Face(pFace);
- return !retCharmap && retIndex;
-}
-FX_BOOL CFX_FontMgrImp::VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode) {
- if (NULL == pFont) {
- return FALSE;
- }
- FXFT_Face pFace = ((CFX_Font*)pFont->GetDevFont())->GetFace();
- FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
- if (0 != FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE)) {
- return FALSE;
- }
- if (0 == FXFT_Get_Char_Index(pFace, wcUnicode)) {
- FXFT_Set_Charmap(pFace, charmap);
- return FALSE;
- }
- return TRUE;
-}
-IFX_Font* CFX_FontMgrImp::GetFontByLanguage(FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily) {
- return GetFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles,
- pszFontFamily);
-}
-IFX_Font* CFX_FontMgrImp::LoadFont(const uint8_t* pBuffer,
- int32_t iLength,
- int32_t iFaceIndex,
- int32_t* pFaceCount) {
- void* Hash[2] = {(void*)(uintptr_t)pBuffer, (void*)(uintptr_t)iLength};
- FX_DWORD dwHash =
- FX_HashCode_String_GetA((const FX_CHAR*)Hash, 2 * sizeof(void*));
- IFX_FileAccess* pFontAccess = NULL;
- if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
- }
- if (NULL != pFontAccess) {
- return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
- } else {
- return NULL;
- }
-}
-IFX_Font* CFX_FontMgrImp::LoadFont(const FX_WCHAR* pszFileName,
- int32_t iFaceIndex,
- int32_t* pFaceCount) {
- CFX_ByteString bsHash;
- bsHash += CFX_WideString(pszFileName).UTF8Encode();
- FX_DWORD dwHash =
- FX_HashCode_String_GetA((const FX_CHAR*)bsHash, bsHash.GetLength());
- IFX_FileAccess* pFontAccess = NULL;
- if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
- pFontAccess = FX_CreateDefaultFileAccess(pszFileName);
- m_Hash2FileAccess.SetAt(dwHash, pFontAccess);
- }
- if (NULL != pFontAccess) {
- return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
- } else {
- return NULL;
- }
-}
-IFX_Font* CFX_FontMgrImp::LoadFont(IFX_Stream* pFontStream,
- int32_t iFaceIndex,
- int32_t* pFaceCount,
- FX_BOOL bSaveStream) {
- void* Hash[1] = {(void*)(uintptr_t)pFontStream};
- FX_DWORD dwHash =
- FX_HashCode_String_GetA((const FX_CHAR*)Hash, 1 * sizeof(void*));
- IFX_FileAccess* pFontAccess = NULL;
- if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
- }
- if (NULL != pFontAccess) {
- return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
- } else {
- return NULL;
- }
-}
-IFX_Font* CFX_FontMgrImp::LoadFont(IFX_FileAccess* pFontAccess,
- int32_t iFaceIndex,
- int32_t* pFaceCount,
- FX_BOOL bWantCache) {
- FX_DWORD dwHash = 0;
- IFX_Font* pFont = NULL;
- if (bWantCache) {
- CFX_ByteString bsHash;
- bsHash.Format("%d, %d", (uintptr_t)pFontAccess, iFaceIndex);
- dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
- if (m_FileAccess2IFXFont.Lookup(dwHash, pFont)) {
- if (NULL != pFont) {
- if (NULL != pFaceCount) {
- *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
- }
- return pFont->Retain();
- }
- }
- }
- CFX_Font* pInternalFont = new CFX_Font;
- IFX_FileRead* pFontStream =
- pFontAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
- if (NULL == pFontStream) {
- delete pInternalFont;
- return NULL;
- }
- if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
- delete pInternalFont;
- pFontStream->Release();
- return NULL;
- }
- pFont = IFX_Font::LoadFont(pInternalFont, this, TRUE);
- if (NULL == pFont) {
- delete pInternalFont;
- pFontStream->Release();
- return NULL;
- }
- if (bWantCache) {
- m_FileAccess2IFXFont.SetAt(dwHash, pFont);
- }
- m_IFXFont2FileRead.SetAt(pFont, pFontStream);
- if (NULL != pFaceCount) {
- *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
- }
- return pFont;
-}
-IFX_Font* CFX_FontMgrImp::LoadFont(const CFX_WideString& wsFaceName,
- int32_t iFaceIndex,
- int32_t* pFaceCount) {
- CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
- CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
- if (!pFontMapper)
- return nullptr;
- IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
- if (!pSystemFontInfo)
- return nullptr;
- IFX_FileRead* pFontStream =
- CreateFontStream(pFontMapper, pSystemFontInfo, iFaceIndex);
- if (!pFontStream)
- return nullptr;
- if (!LoadFace(pFontStream, 0)) {
- pFontStream->Release();
- return nullptr;
- }
- CFX_Font* pInternalFont = new CFX_Font();
- if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
- pFontStream->Release();
- return nullptr;
- }
- IFX_Font* pFont = IFX_Font::LoadFont(pInternalFont, this, FALSE);
- if (!pFont) {
- pFontStream->Release();
- return nullptr;
- }
- m_IFXFont2FileRead.SetAt(pFont, pFontStream);
- if (pFaceCount)
- *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
- return pFont;
-}
-extern "C" {
-unsigned long _ftStreamRead(FXFT_Stream stream,
- unsigned long offset,
- unsigned char* buffer,
- unsigned long count) {
- if (count == 0) {
- return 0;
- }
- IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
- int res = pFile->ReadBlock(buffer, offset, count);
- if (res) {
- return count;
- }
- return 0;
-}
-void _ftStreamClose(FXFT_Stream stream) {}
-};
-
-FXFT_Face CFX_FontMgrImp::LoadFace(IFX_FileRead* pFontStream,
- int32_t iFaceIndex) {
- if (!pFontStream)
- return nullptr;
-
- CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
- pFontMgr->InitFTLibrary();
- FXFT_Library library = pFontMgr->GetFTLibrary();
- if (!library)
- return nullptr;
-
- FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
- FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
- ftStream->base = NULL;
- ftStream->descriptor.pointer = pFontStream;
- ftStream->pos = 0;
- ftStream->size = (unsigned long)pFontStream->GetSize();
- ftStream->read = _ftStreamRead;
- ftStream->close = _ftStreamClose;
-
- FXFT_Open_Args ftArgs;
- FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args));
- ftArgs.flags |= FT_OPEN_STREAM;
- ftArgs.stream = ftStream;
-
- FXFT_Face pFace = NULL;
- if (FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) {
- FX_Free(ftStream);
- return nullptr;
- }
-
- FXFT_Set_Pixel_Sizes(pFace, 0, 64);
- return pFace;
-}
-IFX_FileRead* CFX_FontMgrImp::CreateFontStream(
- CFX_FontMapper* pFontMapper,
- IFX_SystemFontInfo* pSystemFontInfo,
- FX_DWORD index) {
- int iExact = 0;
- void* hFont = pSystemFontInfo->MapFont(
- 0, 0, FXFONT_DEFAULT_CHARSET, 0, pFontMapper->GetFaceName(index), iExact);
- if (!hFont)
- return nullptr;
- FX_DWORD dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
- if (dwFileSize == 0)
- return nullptr;
- uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1);
- dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize);
- return new CFX_MemoryStream(pBuffer, dwFileSize, TRUE);
-}
-IFX_FileRead* CFX_FontMgrImp::CreateFontStream(
- const CFX_ByteString& bsFaceName) {
- CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
- CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
- if (!pFontMapper)
- return nullptr;
- IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
- if (!pSystemFontInfo)
- return nullptr;
- pSystemFontInfo->EnumFontList(pFontMapper);
- for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
- if (pFontMapper->GetFaceName(i) == bsFaceName)
- return CreateFontStream(pFontMapper, pSystemFontInfo, i);
- }
- return nullptr;
-}
-int32_t CFX_FontMgrImp::MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
- FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const CFX_WideString& FontName,
- FX_WCHAR wcUnicode) {
- MatchedFonts.RemoveAll();
- CFX_WideString wsNormalizedFontName = FontName;
- static const int32_t nMax = 0xffff;
- CFX_FontDescriptor* pFont = NULL;
- int32_t nCount = m_InstalledFonts.GetSize();
- for (int32_t i = 0; i < nCount; i++) {
- pFont = m_InstalledFonts[i];
- int32_t nPenalty = CalcPenalty(pFont, wCodePage, dwFontStyles,
- wsNormalizedFontName, wcUnicode);
- if (nPenalty >= 0xFFFF) {
- continue;
- }
- FX_FontDescriptorInfo FontInfo;
- FontInfo.pFont = pFont;
- FontInfo.nPenalty = nPenalty;
- MatchedFonts.Add(FontInfo);
- if (MatchedFonts.GetSize() == nMax) {
- break;
- }
- }
- if (MatchedFonts.GetSize() == 0) {
- return 0;
- }
- CFX_SSortTemplate<FX_FontDescriptorInfo> ssort;
- ssort.ShellSort(MatchedFonts.GetData(), MatchedFonts.GetSize());
- return MatchedFonts.GetSize();
-}
-struct FX_BitCodePage {
- FX_WORD wBit;
- FX_WORD wCodePage;
-};
-static const FX_BitCodePage g_Bit2CodePage[] = {
- {0, 1252}, {1, 1250}, {2, 1251}, {3, 1253}, {4, 1254}, {5, 1255},
- {6, 1256}, {7, 1257}, {8, 1258}, {9, 0}, {10, 0}, {11, 0},
- {12, 0}, {13, 0}, {14, 0}, {15, 0}, {16, 874}, {17, 932},
- {18, 936}, {19, 949}, {20, 950}, {21, 1361}, {22, 0}, {23, 0},
- {24, 0}, {25, 0}, {26, 0}, {27, 0}, {28, 0}, {29, 0},
- {30, 0}, {31, 0}, {32, 0}, {33, 0}, {34, 0}, {35, 0},
- {36, 0}, {37, 0}, {38, 0}, {39, 0}, {40, 0}, {41, 0},
- {42, 0}, {43, 0}, {44, 0}, {45, 0}, {46, 0}, {47, 0},
- {48, 869}, {49, 866}, {50, 865}, {51, 864}, {52, 863}, {53, 862},
- {54, 861}, {55, 860}, {56, 857}, {57, 855}, {58, 852}, {59, 775},
- {60, 737}, {61, 708}, {62, 850}, {63, 437},
-};
-FX_WORD FX_GetCodePageBit(FX_WORD wCodePage) {
- for (int32_t i = 0; i < sizeof(g_Bit2CodePage) / sizeof(FX_BitCodePage);
- i++) {
- if (g_Bit2CodePage[i].wCodePage == wCodePage) {
- return g_Bit2CodePage[i].wBit;
- }
- }
- return (FX_WORD)-1;
-}
-FX_WORD FX_GetUnicodeBit(FX_WCHAR wcUnicode) {
- FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wcUnicode);
- if (NULL == x) {
- return 999;
- }
- return x->wBitField;
-}
-int32_t CFX_FontMgrImp::CalcPenalty(CFX_FontDescriptor* pInstalled,
- FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const CFX_WideString& FontName,
- FX_WCHAR wcUnicode) {
- int32_t nPenalty = 30000;
- if (0 != FontName.GetLength()) {
- if (FontName != pInstalled->m_wsFaceName) {
- int32_t i;
- for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
- if (pInstalled->m_wsFamilyNames[i] == FontName) {
- break;
- }
- }
- if (i == pInstalled->m_wsFamilyNames.GetSize()) {
- nPenalty += 0xFFFF;
- } else {
- nPenalty -= 28000;
- }
- } else {
- nPenalty -= 30000;
- }
- if (30000 == nPenalty &&
- 0 == IsPartName(pInstalled->m_wsFaceName, FontName)) {
- int32_t i;
- for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
- if (0 != IsPartName(pInstalled->m_wsFamilyNames[i], FontName)) {
- break;
- }
- }
- if (i == pInstalled->m_wsFamilyNames.GetSize()) {
- nPenalty += 0xFFFF;
- } else {
- nPenalty -= 26000;
- }
- } else {
- nPenalty -= 27000;
- }
- }
- FX_DWORD dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
- if (dwStyleMask & FX_FONTSTYLE_Bold) {
- nPenalty += 4500;
- }
- if (dwStyleMask & FX_FONTSTYLE_FixedPitch) {
- nPenalty += 10000;
- }
- if (dwStyleMask & FX_FONTSTYLE_Italic) {
- nPenalty += 10000;
- }
- if (dwStyleMask & FX_FONTSTYLE_Serif) {
- nPenalty += 500;
- }
- if (dwStyleMask & FX_FONTSTYLE_Symbolic) {
- nPenalty += 0xFFFF;
- }
- if (nPenalty >= 0xFFFF) {
- return 0xFFFF;
- }
- FX_WORD wBit =
- ((0 == wCodePage || 0xFFFF == wCodePage) ? (FX_WORD)-1
- : FX_GetCodePageBit(wCodePage));
- if (wBit != (FX_WORD)-1) {
- FXSYS_assert(wBit < 64);
- if (0 == (pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32)))) {
- nPenalty += 0xFFFF;
- } else {
- nPenalty -= 60000;
- }
- }
- wBit =
- ((0 == wcUnicode || 0xFFFE == wcUnicode) ? (FX_WORD)999
- : FX_GetUnicodeBit(wcUnicode));
- if (wBit != (FX_WORD)999) {
- FXSYS_assert(wBit < 128);
- if (0 == (pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32)))) {
- nPenalty += 0xFFFF;
- } else {
- nPenalty -= 60000;
- }
- }
- return nPenalty;
-}
-void CFX_FontMgrImp::ClearFontCache() {
- FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- CFX_FontDescriptorInfos* pDescs;
- m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
- if (NULL != pDescs) {
- delete pDescs;
- }
- }
- pos = m_FileAccess2IFXFont.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- IFX_Font* pFont;
- m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
- if (NULL != pFont) {
- pFont->Release();
- }
- }
- pos = m_IFXFont2FileRead.GetStartPosition();
- while (pos) {
- IFX_Font* pFont;
- IFX_FileRead* pFileRead;
- m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
- pFileRead->Release();
- }
-}
-void CFX_FontMgrImp::RemoveFont(IFX_Font* pEFont) {
- if (NULL == pEFont) {
- return;
- }
- IFX_FileRead* pFileRead;
- if (m_IFXFont2FileRead.Lookup(pEFont, pFileRead)) {
- pFileRead->Release();
- m_IFXFont2FileRead.RemoveKey(pEFont);
- }
- FX_POSITION pos;
- pos = m_FileAccess2IFXFont.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- IFX_Font* pCFont;
- m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pCFont);
- if (pCFont == pEFont) {
- m_FileAccess2IFXFont.RemoveKey(dwHash);
- break;
- }
- }
- pos = m_Hash2Fonts.GetStartPosition();
- while (pos) {
- FX_DWORD dwHash;
- CFX_ArrayTemplate<IFX_Font*>* pFonts;
- m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
- if (NULL != pFonts) {
- for (int32_t i = 0; i < pFonts->GetSize(); i++) {
- if (pFonts->GetAt(i) == pEFont) {
- pFonts->SetAt(i, NULL);
- }
- }
- } else {
- m_Hash2Fonts.RemoveKey(dwHash);
- }
- }
-}
-void CFX_FontMgrImp::ReportFace(FXFT_Face pFace,
- CFX_FontDescriptors& Fonts,
- IFX_FileAccess* pFontAccess) {
- if (0 == (pFace->face_flags & FT_FACE_FLAG_SCALABLE)) {
- return;
- }
- CFX_FontDescriptor* pFont = new CFX_FontDescriptor;
- pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0;
- pFont->m_dwFontStyles |= FXFT_Is_Face_Italic(pFace) ? FX_FONTSTYLE_Italic : 0;
- pFont->m_dwFontStyles |= GetFlags(pFace);
- CFX_WordArray Charsets;
- GetCharsets(pFace, Charsets);
- GetUSBCSB(pFace, pFont->m_dwUsb, pFont->m_dwCsb);
- unsigned long nLength = 0;
- FT_ULong dwTag;
- uint8_t* pTable = NULL;
- FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
- unsigned int error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, NULL, &nLength);
- if (0 == error && 0 != nLength) {
- pTable = FX_Alloc(uint8_t, nLength);
- error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, pTable, NULL);
- if (0 != error) {
- FX_Free(pTable);
- pTable = NULL;
- }
- }
- GetNames(pTable, pFont->m_wsFamilyNames);
- if (NULL != pTable) {
- FX_Free(pTable);
- }
- pFont->m_wsFamilyNames.Add(CFX_ByteString(pFace->family_name).UTF8Decode());
- pFont->m_wsFaceName =
- CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace));
- pFont->m_nFaceIndex = pFace->face_index;
- if (pFontAccess)
- pFont->m_pFileAccess = pFontAccess->Retain();
- else
- pFont->m_pFileAccess = nullptr;
- Fonts.Add(pFont);
-}
-void CFX_FontMgrImp::ReportFaces(IFX_FileRead* pFontStream) {
- int32_t index = 0;
- int32_t num_faces = 0;
- do {
- FXFT_Face pFace = LoadFace(pFontStream, index++);
- if (!pFace)
- continue;
- // All faces keep number of faces. It can be retrieved from any one face.
- if (!num_faces)
- num_faces = pFace->num_faces;
- ReportFace(pFace, m_InstalledFonts, nullptr);
- if (FXFT_Get_Face_External_Stream(pFace))
- FXFT_Clear_Face_External_Stream(pFace);
- FXFT_Done_Face(pFace);
- } while (index < num_faces);
-}
-FX_DWORD CFX_FontMgrImp::GetFlags(FXFT_Face pFace) {
- FX_DWORD flag = 0;
- if (FT_IS_FIXED_WIDTH(pFace)) {
- flag |= FX_FONTSTYLE_FixedPitch;
- }
- TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
- if (!pOS2) {
- return flag;
- }
- if (pOS2->ulCodePageRange1 & (1 << 31)) {
- flag |= FX_FONTSTYLE_Symbolic;
- }
- if (pOS2->panose[0] == 2) {
- uint8_t uSerif = pOS2->panose[1];
- if ((uSerif > 1 && uSerif < 10) || uSerif > 13) {
- flag |= FX_FONTSTYLE_Serif;
- }
- }
- return flag;
-}
-#define GetUInt8(p) ((uint8_t)((p)[0]))
-#define GetUInt16(p) ((uint16_t)((p)[0] << 8 | (p)[1]))
-#define GetUInt32(p) \
- ((uint32_t)((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3]))
-void CFX_FontMgrImp::GetNames(const uint8_t* name_table,
- CFX_WideStringArray& Names) {
- if (NULL == name_table) {
- return;
- }
- uint8_t* lpTable = (uint8_t*)name_table;
- CFX_WideString wsFamily;
- uint8_t* sp = lpTable + 2;
- uint8_t* lpNameRecord = lpTable + 6;
- uint16_t nNameCount = GetUInt16(sp);
- uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
- for (uint16_t j = 0; j < nNameCount; j++) {
- uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
- if (nNameID != 1) {
- continue;
- }
- uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
- uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
- uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
- wsFamily.Empty();
- if (nPlatformID != 1) {
- for (uint16_t k = 0; k < nNameLength / 2; k++) {
- FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
- wsFamily += wcTemp;
- }
- Names.Add(wsFamily);
- } else {
- for (uint16_t k = 0; k < nNameLength; k++) {
- FX_WCHAR wcTemp = GetUInt8(lpStr + nNameOffset + k);
- wsFamily += wcTemp;
- }
- Names.Add(wsFamily);
- }
- }
-}
-#undef GetUInt8
-#undef GetUInt16
-#undef GetUInt32
-struct FX_BIT2CHARSET {
- FX_WORD wBit;
- FX_WORD wCharset;
-};
-FX_BIT2CHARSET g_FX_Bit2Charset1[16] = {
- {1 << 0, FX_CHARSET_ANSI},
- {1 << 1, FX_CHARSET_MSWin_EasterEuropean},
- {1 << 2, FX_CHARSET_MSWin_Cyrillic},
- {1 << 3, FX_CHARSET_MSWin_Greek},
- {1 << 4, FX_CHARSET_MSWin_Turkish},
- {1 << 5, FX_CHARSET_MSWin_Hebrew},
- {1 << 6, FX_CHARSET_MSWin_Arabic},
- {1 << 7, FX_CHARSET_MSWin_Baltic},
- {1 << 8, FX_CHARSET_MSWin_Vietnamese},
- {1 << 9, FX_CHARSET_Default},
- {1 << 10, FX_CHARSET_Default},
- {1 << 11, FX_CHARSET_Default},
- {1 << 12, FX_CHARSET_Default},
- {1 << 13, FX_CHARSET_Default},
- {1 << 14, FX_CHARSET_Default},
- {1 << 15, FX_CHARSET_Default},
-};
-FX_BIT2CHARSET g_FX_Bit2Charset2[16] = {
- {1 << 0, FX_CHARSET_Thai},
- {1 << 1, FX_CHARSET_ShiftJIS},
- {1 << 2, FX_CHARSET_ChineseSimplified},
- {1 << 3, FX_CHARSET_Korean},
- {1 << 4, FX_CHARSET_ChineseTriditional},
- {1 << 5, FX_CHARSET_Johab},
- {1 << 6, FX_CHARSET_Default},
- {1 << 7, FX_CHARSET_Default},
- {1 << 8, FX_CHARSET_Default},
- {1 << 9, FX_CHARSET_Default},
- {1 << 10, FX_CHARSET_Default},
- {1 << 11, FX_CHARSET_Default},
- {1 << 12, FX_CHARSET_Default},
- {1 << 13, FX_CHARSET_Default},
- {1 << 14, FX_CHARSET_OEM},
- {1 << 15, FX_CHARSET_Symbol},
-};
-FX_BIT2CHARSET g_FX_Bit2Charset3[16] = {
- {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
- {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
- {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
- {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
- {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
- {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
- {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
- {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_Default},
-};
-FX_BIT2CHARSET g_FX_Bit2Charset4[16] = {
- {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
- {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
- {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
- {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
- {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
- {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
- {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
- {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_US},
-};
-#define CODEPAGERANGE_IMPLEMENT(n) \
- for (int32_t i = 0; i < 16; i++) { \
- if ((a##n & g_FX_Bit2Charset##n[i].wBit) != 0) { \
- Charsets.Add(g_FX_Bit2Charset##n[i].wCharset); \
- } \
- }
-void CFX_FontMgrImp::GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets) {
- Charsets.RemoveAll();
- TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
- if (NULL != pOS2) {
- FX_WORD a1, a2, a3, a4;
- a1 = pOS2->ulCodePageRange1 & 0x0000ffff;
- CODEPAGERANGE_IMPLEMENT(1);
- a2 = (pOS2->ulCodePageRange1 >> 16) & 0x0000ffff;
- CODEPAGERANGE_IMPLEMENT(2);
- a3 = pOS2->ulCodePageRange2 & 0x0000ffff;
- CODEPAGERANGE_IMPLEMENT(3);
- a4 = (pOS2->ulCodePageRange2 >> 16) & 0x0000ffff;
- CODEPAGERANGE_IMPLEMENT(4);
- } else {
- Charsets.Add(FX_CHARSET_Default);
- }
-}
-#undef CODEPAGERANGE_IMPLEMENT
-void CFX_FontMgrImp::GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB) {
- TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
- if (NULL != pOS2) {
- USB[0] = pOS2->ulUnicodeRange1;
- USB[1] = pOS2->ulUnicodeRange2;
- USB[2] = pOS2->ulUnicodeRange3;
- USB[3] = pOS2->ulUnicodeRange4;
- CSB[0] = pOS2->ulCodePageRange1;
- CSB[1] = pOS2->ulCodePageRange2;
- } else {
- USB[0] = 0;
- USB[1] = 0;
- USB[2] = 0;
- USB[3] = 0;
- CSB[0] = 0;
- CSB[1] = 0;
- }
-}
-int32_t CFX_FontMgrImp::IsPartName(const CFX_WideString& Name1,
- const CFX_WideString& Name2) {
- if (Name1.Find((const FX_WCHAR*)Name2) != -1) {
- return 1;
- }
- return 0;
-}
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/src/fxcrt/extension.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_stdfontmgr.h"
+#include "fx_fontutils.h"
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+IFX_FontMgr* IFX_FontMgr::Create(FX_LPEnumAllFonts pEnumerator,
+ FX_LPMatchFont pMatcher,
+ void* pUserData) {
+ return new CFX_StdFontMgrImp(pEnumerator, pMatcher, pUserData);
+}
+CFX_StdFontMgrImp::CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator,
+ FX_LPMatchFont pMatcher,
+ void* pUserData)
+ : m_pMatcher(pMatcher),
+ m_pEnumerator(pEnumerator),
+ m_FontFaces(),
+ m_Fonts(),
+ m_CPFonts(8),
+ m_FamilyFonts(16),
+ m_UnicodeFonts(16),
+ m_BufferFonts(4),
+ m_FileFonts(4),
+ m_StreamFonts(4),
+ m_DeriveFonts(4),
+ m_pUserData(pUserData) {
+ if (m_pEnumerator != NULL) {
+ m_pEnumerator(m_FontFaces, m_pUserData, NULL, 0xFEFF);
+ }
+ if (m_pMatcher == NULL) {
+ m_pMatcher = FX_DefFontMatcher;
+ }
+ FXSYS_assert(m_pMatcher != NULL);
+}
+CFX_StdFontMgrImp::~CFX_StdFontMgrImp() {
+ m_FontFaces.RemoveAll();
+ m_CPFonts.RemoveAll();
+ m_FamilyFonts.RemoveAll();
+ m_UnicodeFonts.RemoveAll();
+ m_BufferFonts.RemoveAll();
+ m_FileFonts.RemoveAll();
+ m_StreamFonts.RemoveAll();
+ m_DeriveFonts.RemoveAll();
+ for (int32_t i = m_Fonts.GetUpperBound(); i >= 0; i--) {
+ IFX_Font* pFont = (IFX_Font*)m_Fonts[i];
+ if (pFont != NULL) {
+ pFont->Release();
+ }
+ }
+ m_Fonts.RemoveAll();
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByCodePage(
+ FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ FX_DWORD dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ IFX_Font* pFont = NULL;
+ if (m_CPFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
+ }
+ FX_LPCFONTDESCRIPTOR pFD;
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(NULL, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(NULL, dwFontStyles, FALSE, wCodePage)) == NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD != NULL);
+ pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByCharset(
+ uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return GetDefFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
+ pszFontFamily);
+}
+#define _FX_USEGASFONTMGR_
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByUnicode(
+ FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ FGAS_LPCFONTUSB pRet = FGAS_GetUnicodeBitField(wUnicode);
+ if (pRet->wBitField == 999) {
+ return NULL;
+ }
+ FX_DWORD dwHash =
+ FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
+ IFX_Font* pFont = NULL;
+ if (m_UnicodeFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : NULL;
+ }
+#ifdef _FX_USEGASFONTMGR_
+ FX_LPCFONTDESCRIPTOR pFD =
+ FindFont(pszFontFamily, dwFontStyles, FALSE, pRet->wCodePage,
+ pRet->wBitField, wUnicode);
+ if (pFD == NULL && pszFontFamily) {
+ pFD = FindFont(NULL, dwFontStyles, FALSE, pRet->wCodePage, pRet->wBitField,
+ wUnicode);
+ }
+ if (pFD == NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD);
+ FX_WORD wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
+ const FX_WCHAR* pFontFace = pFD->wsFontFace;
+ pFont = IFX_Font::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
+#else
+ CFX_FontMapper* pBuiltinMapper =
+ CFX_GEModule::Get()->GetFontMgr()->m_pBuiltinMapper;
+ if (pBuiltinMapper == NULL) {
+ return NULL;
+ }
+ int32_t iWeight =
+ (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ int italic_angle = 0;
+ FXFT_Face ftFace = pBuiltinMapper->FindSubstFontByUnicode(
+ wUnicode, dwFontStyles, iWeight, italic_angle);
+ if (ftFace == NULL) {
+ return NULL;
+ }
+ CFX_Font* pFXFont = new CFX_Font;
+ pFXFont->m_Face = ftFace;
+ pFXFont->m_pFontData = FXFT_Get_Face_Stream_Base(ftFace);
+ pFXFont->m_dwSize = FXFT_Get_Face_Stream_Size(ftFace);
+ pFont = IFX_Font::LoadFont(pFXFont, this);
+ FX_WORD wCodePage = pRet->wCodePage;
+ CFX_WideString wsPsName = pFXFont->GetPsName();
+ const FX_WCHAR* pFontFace = wsPsName;
+#endif
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_UnicodeFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByLanguage(
+ FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return GetDefFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage),
+ dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage) {
+ FX_DWORD dwHash =
+ FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
+ IFX_Font* pFont = NULL;
+ if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
+ }
+ FX_LPCFONTDESCRIPTOR pFD = NULL;
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, FALSE, wCodePage)) ==
+ NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD != NULL);
+ if (wCodePage == 0xFFFF) {
+ wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
+ }
+ pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ m_CPFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(const uint8_t* pBuffer, int32_t iLength) {
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ IFX_Font* pFont = NULL;
+ if (m_BufferFonts.Lookup((void*)pBuffer, (void*&)pFont)) {
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = IFX_Font::LoadFont(pBuffer, iLength, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_BufferFonts.SetAt((void*)pBuffer, pFont);
+ return pFont->Retain();
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(const FX_WCHAR* pszFileName) {
+ FXSYS_assert(pszFileName != NULL);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszFileName, -1);
+ IFX_Font* pFont = NULL;
+ if (m_FileFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) {
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = IFX_Font::LoadFont(pszFileName, NULL);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_FileFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ return pFont->Retain();
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Stream* pFontStream,
+ const FX_WCHAR* pszFontAlias,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage,
+ FX_BOOL bSaveStream) {
+ FXSYS_assert(pFontStream != NULL && pFontStream->GetLength() > 0);
+ IFX_Font* pFont = NULL;
+ if (m_StreamFonts.Lookup((void*)pFontStream, (void*&)pFont)) {
+ if (pFont != NULL) {
+ if (pszFontAlias != NULL) {
+ FX_DWORD dwHash =
+ FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ }
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ }
+ pFont = IFX_Font::LoadFont(pFontStream, this, bSaveStream);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_StreamFonts.SetAt((void*)pFontStream, (void*)pFont);
+ if (pszFontAlias != NULL) {
+ FX_DWORD dwHash =
+ FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ }
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Font* pSrcFont,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage) {
+ FXSYS_assert(pSrcFont != NULL);
+ if (pSrcFont->GetFontStyles() == dwFontStyles) {
+ return pSrcFont->Retain();
+ }
+ void* buffer[3] = {pSrcFont, (void*)(uintptr_t)dwFontStyles,
+ (void*)(uintptr_t)wCodePage};
+ FX_DWORD dwHash =
+ FX_HashCode_String_GetA((const FX_CHAR*)buffer, 3 * sizeof(void*));
+ IFX_Font* pFont = NULL;
+ if (m_DeriveFonts.GetCount() > 0) {
+ m_DeriveFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont);
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
+ if (pFont != NULL) {
+ m_DeriveFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont);
+ int32_t index = m_Fonts.Find(pFont);
+ if (index < 0) {
+ m_Fonts.Add(pFont);
+ pFont->Retain();
+ }
+ return pFont;
+ }
+ return NULL;
+}
+void CFX_StdFontMgrImp::ClearFontCache() {
+ int32_t iCount = m_Fonts.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFX_Font* pFont = (IFX_Font*)m_Fonts[i];
+ if (pFont != NULL) {
+ pFont->Reset();
+ }
+ }
+}
+void CFX_StdFontMgrImp::RemoveFont(CFX_MapPtrToPtr& fontMap, IFX_Font* pFont) {
+ FX_POSITION pos = fontMap.GetStartPosition();
+ void* pKey;
+ void* pFind;
+ while (pos != NULL) {
+ pFind = NULL;
+ fontMap.GetNextAssoc(pos, pKey, pFind);
+ if (pFind != (void*)pFont) {
+ continue;
+ }
+ fontMap.RemoveKey(pKey);
+ break;
+ }
+}
+void CFX_StdFontMgrImp::RemoveFont(IFX_Font* pFont) {
+ RemoveFont(m_CPFonts, pFont);
+ RemoveFont(m_FamilyFonts, pFont);
+ RemoveFont(m_UnicodeFonts, pFont);
+ RemoveFont(m_BufferFonts, pFont);
+ RemoveFont(m_FileFonts, pFont);
+ RemoveFont(m_StreamFonts, pFont);
+ RemoveFont(m_DeriveFonts, pFont);
+ int32_t iFind = m_Fonts.Find(pFont);
+ if (iFind > -1) {
+ m_Fonts.RemoveAt(iFind, 1);
+ }
+}
+FX_LPCFONTDESCRIPTOR CFX_StdFontMgrImp::FindFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_DWORD dwMatchFlags,
+ FX_WORD wCodePage,
+ FX_DWORD dwUSB,
+ FX_WCHAR wUnicode) {
+ if (m_pMatcher == NULL) {
+ return NULL;
+ }
+ FX_FONTMATCHPARAMS params;
+ FX_memset(&params, 0, sizeof(params));
+ params.dwUSB = dwUSB;
+ params.wUnicode = wUnicode;
+ params.wCodePage = wCodePage;
+ params.pwsFamily = pszFontFamily;
+ params.dwFontStyles = dwFontStyles;
+ params.dwMatchFlags = dwMatchFlags;
+ FX_LPCFONTDESCRIPTOR pDesc = m_pMatcher(&params, m_FontFaces, m_pUserData);
+ if (pDesc) {
+ return pDesc;
+ }
+ if (pszFontFamily && m_pEnumerator) {
+ CFX_FontDescriptors namedFonts;
+ m_pEnumerator(namedFonts, m_pUserData, pszFontFamily, wUnicode);
+ params.pwsFamily = NULL;
+ pDesc = m_pMatcher(&params, namedFonts, m_pUserData);
+ if (pDesc == NULL) {
+ return NULL;
+ }
+ for (int32_t i = m_FontFaces.GetSize() - 1; i >= 0; i--) {
+ FX_LPCFONTDESCRIPTOR pMatch = m_FontFaces.GetPtrAt(i);
+ if (*pMatch == *pDesc) {
+ return pMatch;
+ }
+ }
+ int index = m_FontFaces.Add(*pDesc);
+ return m_FontFaces.GetPtrAt(index);
+ }
+ return NULL;
+}
+FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams,
+ const CFX_FontDescriptors& fonts,
+ void* pUserData) {
+ FX_LPCFONTDESCRIPTOR pBestFont = NULL;
+ int32_t iBestSimilar = 0;
+ FX_BOOL bMatchStyle =
+ (pParams->dwMatchFlags & FX_FONTMATCHPARA_MacthStyle) > 0;
+ int32_t iCount = fonts.GetSize();
+ for (int32_t i = 0; i < iCount; ++i) {
+ FX_LPCFONTDESCRIPTOR pFont = fonts.GetPtrAt(i);
+ if ((pFont->dwFontStyles & FX_FONTSTYLE_BoldItalic) ==
+ FX_FONTSTYLE_BoldItalic) {
+ continue;
+ }
+ if (pParams->pwsFamily) {
+ if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace)) {
+ continue;
+ }
+ if (pFont->uCharSet == FX_CHARSET_Symbol) {
+ return pFont;
+ }
+ }
+ if (pFont->uCharSet == FX_CHARSET_Symbol) {
+ continue;
+ }
+ if (pParams->wCodePage != 0xFFFF) {
+ if (FX_GetCodePageFromCharset(pFont->uCharSet) != pParams->wCodePage) {
+ continue;
+ }
+ } else {
+ if (pParams->dwUSB < 128) {
+ FX_DWORD dwByte = pParams->dwUSB / 32;
+ FX_DWORD dwUSB = 1 << (pParams->dwUSB % 32);
+ if ((pFont->FontSignature.fsUsb[dwByte] & dwUSB) == 0) {
+ continue;
+ }
+ }
+ }
+ if (bMatchStyle) {
+ if ((pFont->dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F)) {
+ return pFont;
+ } else {
+ continue;
+ }
+ }
+ if (pParams->pwsFamily != NULL) {
+ if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace) == 0) {
+ return pFont;
+ }
+ }
+ int32_t iSimilarValue = FX_GetSimilarValue(pFont, pParams->dwFontStyles);
+ if (iBestSimilar < iSimilarValue) {
+ iBestSimilar = iSimilarValue;
+ pBestFont = pFont;
+ }
+ }
+ return iBestSimilar < 1 ? NULL : pBestFont;
+}
+int32_t FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles) {
+ int32_t iValue = 0;
+ if ((dwFontStyles & FX_FONTSTYLE_Symbolic) ==
+ (pFont->dwFontStyles & FX_FONTSTYLE_Symbolic)) {
+ iValue += 64;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_FixedPitch) ==
+ (pFont->dwFontStyles & FX_FONTSTYLE_FixedPitch)) {
+ iValue += 32;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_Serif) ==
+ (pFont->dwFontStyles & FX_FONTSTYLE_Serif)) {
+ iValue += 16;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_Script) ==
+ (pFont->dwFontStyles & FX_FONTSTYLE_Script)) {
+ iValue += 8;
+ }
+ return iValue;
+}
+FX_LPMatchFont FX_GetDefFontMatchor() {
+ return FX_DefFontMatcher;
+}
+FX_DWORD FX_GetGdiFontStyles(const LOGFONTW& lf) {
+ FX_DWORD dwStyles = 0;
+ if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH) {
+ dwStyles |= FX_FONTSTYLE_FixedPitch;
+ }
+ uint8_t nFamilies = lf.lfPitchAndFamily & 0xF0;
+ if (nFamilies == FF_ROMAN) {
+ dwStyles |= FX_FONTSTYLE_Serif;
+ }
+ if (nFamilies == FF_SCRIPT) {
+ dwStyles |= FX_FONTSTYLE_Script;
+ }
+ if (lf.lfCharSet == SYMBOL_CHARSET) {
+ dwStyles |= FX_FONTSTYLE_Symbolic;
+ }
+ return dwStyles;
+}
+static int32_t CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX* lpelfe,
+ NEWTEXTMETRICEX* lpntme,
+ DWORD dwFontType,
+ LPARAM lParam) {
+ if (dwFontType != TRUETYPE_FONTTYPE) {
+ return 1;
+ }
+ const LOGFONTW& lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
+ if (lf.lfFaceName[0] == L'@') {
+ return 1;
+ }
+ FX_LPFONTDESCRIPTOR pFont = FX_Alloc(FX_FONTDESCRIPTOR, 1);
+ FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR));
+ pFont->uCharSet = lf.lfCharSet;
+ pFont->dwFontStyles = FX_GetGdiFontStyles(lf);
+ FXSYS_wcsncpy(pFont->wsFontFace, (const FX_WCHAR*)lf.lfFaceName, 31);
+ pFont->wsFontFace[31] = 0;
+ FX_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig,
+ sizeof(lpntme->ntmFontSig));
+ ((CFX_FontDescriptors*)lParam)->Add(*pFont);
+ FX_Free(pFont);
+ return 1;
+}
+static void FX_EnumGdiFonts(CFX_FontDescriptors& fonts,
+ void* pUserData,
+ const FX_WCHAR* pwsFaceName,
+ FX_WCHAR wUnicode) {
+ HDC hDC = ::GetDC(NULL);
+ LOGFONTW lfFind;
+ FX_memset(&lfFind, 0, sizeof(lfFind));
+ lfFind.lfCharSet = DEFAULT_CHARSET;
+ if (pwsFaceName) {
+ FXSYS_wcsncpy((FX_WCHAR*)lfFind.lfFaceName, pwsFaceName, 31);
+ lfFind.lfFaceName[31] = 0;
+ }
+ EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind,
+ (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)&fonts, 0);
+ ::ReleaseDC(NULL, hDC);
+}
+FX_LPEnumAllFonts FX_GetDefFontEnumerator() {
+ return FX_EnumGdiFonts;
+}
+#else
+const FX_CHAR* g_FontFolders[] = {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+ "/usr/share/fonts", "/usr/share/X11/fonts/Type1",
+ "/usr/share/X11/fonts/TTF", "/usr/local/share/fonts",
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts",
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+ "/system/fonts",
+#endif
+};
+CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() {
+ for (int32_t i = 0; i < sizeof(g_FontFolders) / sizeof(const FX_CHAR*); i++) {
+ m_FolderPaths.Add(g_FontFolders[i]);
+ }
+}
+CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() {
+Restart:
+ void* pCurHandle =
+ m_FolderQueue.GetSize() == 0
+ ? NULL
+ : m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
+ if (NULL == pCurHandle) {
+ if (m_FolderPaths.GetSize() < 1) {
+ return "";
+ }
+ pCurHandle = FX_OpenFolder(m_FolderPaths[m_FolderPaths.GetSize() - 1]);
+ FX_HandleParentPath hpp;
+ hpp.pFileHandle = pCurHandle;
+ hpp.bsParentPath = m_FolderPaths[m_FolderPaths.GetSize() - 1];
+ m_FolderQueue.Add(hpp);
+ }
+ CFX_ByteString bsName;
+ FX_BOOL bFolder;
+ CFX_ByteString bsFolderSpearator =
+ CFX_ByteString::FromUnicode(CFX_WideString(FX_GetFolderSeparator()));
+ while (TRUE) {
+ if (!FX_GetNextFile(pCurHandle, bsName, bFolder)) {
+ FX_CloseFolder(pCurHandle);
+ m_FolderQueue.RemoveAt(m_FolderQueue.GetSize() - 1);
+ if (m_FolderQueue.GetSize() == 0) {
+ m_FolderPaths.RemoveAt(m_FolderPaths.GetSize() - 1);
+ if (m_FolderPaths.GetSize() == 0) {
+ return "";
+ } else {
+ goto Restart;
+ }
+ }
+ pCurHandle =
+ m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
+ continue;
+ }
+ if (bsName == "." || bsName == "..") {
+ continue;
+ }
+ if (bFolder) {
+ FX_HandleParentPath hpp;
+ hpp.bsParentPath =
+ m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
+ bsFolderSpearator + bsName;
+ hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath);
+ if (hpp.pFileHandle == NULL) {
+ continue;
+ }
+ m_FolderQueue.Add(hpp);
+ pCurHandle = hpp.pFileHandle;
+ continue;
+ }
+ bsName =
+ m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath +
+ bsFolderSpearator + bsName;
+ break;
+ }
+ return bsName;
+}
+FX_POSITION CFX_FontSourceEnum_File::GetStartPosition(void* pUserData) {
+ m_wsNext = GetNextFile().UTF8Decode();
+ if (0 == m_wsNext.GetLength()) {
+ return (FX_POSITION)0;
+ }
+ return (FX_POSITION)-1;
+}
+IFX_FileAccess* CFX_FontSourceEnum_File::GetNext(FX_POSITION& pos,
+ void* pUserData) {
+ IFX_FileAccess* pAccess = FX_CreateDefaultFileAccess(m_wsNext);
+ m_wsNext = GetNextFile().UTF8Decode();
+ pos = 0 != m_wsNext.GetLength() ? pAccess : NULL;
+ return (IFX_FileAccess*)pAccess;
+}
+IFX_FontSourceEnum* FX_CreateDefaultFontSourceEnum() {
+ return (IFX_FontSourceEnum*)new CFX_FontSourceEnum_File;
+}
+IFX_FontMgr* IFX_FontMgr::Create(IFX_FontSourceEnum* pFontEnum,
+ IFX_FontMgrDelegate* pDelegate,
+ void* pUserData) {
+ if (NULL == pFontEnum) {
+ return NULL;
+ }
+ CFX_FontMgrImp* pFontMgr =
+ new CFX_FontMgrImp(pFontEnum, pDelegate, pUserData);
+ if (pFontMgr->EnumFonts()) {
+ return pFontMgr;
+ }
+ delete pFontMgr;
+ return NULL;
+}
+CFX_FontMgrImp::CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum,
+ IFX_FontMgrDelegate* pDelegate,
+ void* pUserData)
+ : m_pFontSource(pFontEnum),
+ m_pDelegate(pDelegate),
+ m_pUserData(pUserData) {}
+
+FX_BOOL CFX_FontMgrImp::EnumFontsFromFontMapper() {
+ CFX_FontMapper* pFontMapper =
+ CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
+ if (!pFontMapper)
+ return FALSE;
+ IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
+ if (!pSystemFontInfo)
+ return FALSE;
+ pSystemFontInfo->EnumFontList(pFontMapper);
+ for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
+ IFX_FileRead* pFontStream =
+ CreateFontStream(pFontMapper, pSystemFontInfo, i);
+ if (!pFontStream)
+ continue;
+ ReportFaces(pFontStream);
+ pFontStream->Release();
+ }
+ if (m_InstalledFonts.GetSize() == 0)
+ return FALSE;
+ return TRUE;
+}
+FX_BOOL CFX_FontMgrImp::EnumFontsFromFiles() {
+ CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
+ FX_POSITION pos = m_pFontSource->GetStartPosition();
+ IFX_FileAccess* pFontSource = nullptr;
+ IFX_FileRead* pFontStream = nullptr;
+ while (pos) {
+ pFontSource = m_pFontSource->GetNext(pos);
+ pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
+ if (!pFontStream) {
+ pFontSource->Release();
+ continue;
+ }
+ ReportFaces(pFontStream);
+ pFontStream->Release();
+ pFontSource->Release();
+ }
+ if (m_InstalledFonts.GetSize() == 0)
+ return FALSE;
+ return TRUE;
+}
+FX_BOOL CFX_FontMgrImp::EnumFonts() {
+ if (EnumFontsFromFontMapper())
+ return TRUE;
+ return EnumFontsFromFiles();
+}
+void CFX_FontMgrImp::Release() {
+ for (int32_t i = 0; i < m_InstalledFonts.GetSize(); i++) {
+ delete m_InstalledFonts[i];
+ }
+ FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_FontDescriptorInfos* pDescs;
+ m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
+ if (NULL != pDescs) {
+ delete pDescs;
+ }
+ }
+ pos = m_Hash2Fonts.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_ArrayTemplate<IFX_Font*>* pFonts;
+ m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
+ if (NULL != pFonts) {
+ delete pFonts;
+ }
+ }
+ m_Hash2Fonts.RemoveAll();
+ pos = m_Hash2FileAccess.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_FileAccess* pFileAccess;
+ m_Hash2FileAccess.GetNextAssoc(pos, dwHash, pFileAccess);
+ if (NULL != pFileAccess) {
+ pFileAccess->Release();
+ }
+ }
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
+ if (NULL != pFont) {
+ pFont->Release();
+ }
+ }
+ pos = m_IFXFont2FileRead.GetStartPosition();
+ while (pos) {
+ IFX_Font* pFont;
+ IFX_FileRead* pFileRead;
+ m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
+ pFileRead->Release();
+ }
+ delete this;
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByCodePage(FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCodePage(
+ this, wCodePage, dwFontStyles,
+ pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByCharset(uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return NULL == m_pDelegate ? NULL
+ : m_pDelegate->GetDefFontByCharset(
+ this, nCharset, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByUnicode(FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return NULL == m_pDelegate ? NULL
+ : m_pDelegate->GetDefFontByUnicode(
+ this, wUnicode, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByLanguage(FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByLanguage(
+ this, wLanguage, dwFontStyles,
+ pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetFontByCodePage(FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ CFX_ByteString bsHash;
+ bsHash.Format("%d, %d", wCodePage, dwFontStyles);
+ bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
+ FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ CFX_ArrayTemplate<IFX_Font*>* pFonts = NULL;
+ IFX_Font* pFont = NULL;
+ if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
+ if (NULL == pFonts) {
+ return NULL;
+ }
+ if (0 != pFonts->GetSize()) {
+ return pFonts->GetAt(0)->Retain();
+ }
+ }
+ if (!pFonts)
+ pFonts = new CFX_ArrayTemplate<IFX_Font*>;
+ m_Hash2Fonts.SetAt(dwHash, pFonts);
+ CFX_FontDescriptorInfos* sortedFonts = NULL;
+ if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
+ sortedFonts = new CFX_FontDescriptorInfos;
+ MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
+ CFX_WideString(pszFontFamily), 0);
+ m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
+ }
+ if (sortedFonts->GetSize() == 0) {
+ return NULL;
+ }
+ CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
+ if (pDesc->m_pFileAccess)
+ pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, nullptr);
+ else
+ pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
+ if (NULL != pFont) {
+ pFont->SetLogicalFontStyle(dwFontStyles);
+ }
+ pFonts->Add(pFont);
+ return pFont;
+}
+IFX_Font* CFX_FontMgrImp::GetFontByCharset(uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return GetFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles,
+ pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetFontByUnicode(FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ IFX_Font* pFont = nullptr;
+ if (m_FailedUnicodes2NULL.Lookup(wUnicode, pFont))
+ return nullptr;
+ FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wUnicode);
+ FX_WORD wCodePage = x ? x->wCodePage : 0xFFFF;
+ FX_WORD wBitField = x ? x->wBitField : 0x03E7;
+ CFX_ByteString bsHash;
+ if (wCodePage == 0xFFFF)
+ bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
+ else
+ bsHash.Format("%d, %d", wCodePage, dwFontStyles);
+ bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
+ FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ CFX_ArrayTemplate<IFX_Font*>* pFonts = nullptr;
+ if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
+ if (!pFonts)
+ return nullptr;
+ for (int32_t i = 0; i < pFonts->GetSize(); ++i) {
+ if (VerifyUnicode(pFonts->GetAt(i), wUnicode))
+ return pFonts->GetAt(i)->Retain();
+ }
+ }
+ if (!pFonts)
+ pFonts = new CFX_ArrayTemplate<IFX_Font*>;
+ m_Hash2Fonts.SetAt(dwHash, pFonts);
+ CFX_FontDescriptorInfos* sortedFonts = nullptr;
+ if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
+ sortedFonts = new CFX_FontDescriptorInfos;
+ MatchFonts(*sortedFonts, wCodePage, dwFontStyles,
+ CFX_WideString(pszFontFamily), wUnicode);
+ m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
+ }
+ for (int32_t i = 0; i < sortedFonts->GetSize(); ++i) {
+ CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
+ if (!VerifyUnicode(pDesc, wUnicode))
+ continue;
+ if (pDesc->m_pFileAccess)
+ pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, nullptr);
+ else
+ pFont = LoadFont(pDesc->m_wsFaceName, pDesc->m_nFaceIndex, nullptr);
+ if (!pFont)
+ continue;
+ pFont->SetLogicalFontStyle(dwFontStyles);
+ pFonts->Add(pFont);
+ return pFont;
+ }
+ if (!pszFontFamily)
+ m_FailedUnicodes2NULL.SetAt(wUnicode, nullptr);
+ return nullptr;
+}
+FX_BOOL CFX_FontMgrImp::VerifyUnicode(CFX_FontDescriptor* pDesc,
+ FX_WCHAR wcUnicode) {
+ IFX_FileRead* pFileRead = nullptr;
+ if (pDesc->m_pFileAccess)
+ pFileRead = pDesc->m_pFileAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
+ else
+ pFileRead = CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
+ if (!pFileRead)
+ return FALSE;
+ FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
+ FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
+ FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
+ pFileRead->Release();
+ if (!pFace)
+ return FALSE;
+ if (FXFT_Get_Face_External_Stream(pFace))
+ FXFT_Clear_Face_External_Stream(pFace);
+ FXFT_Done_Face(pFace);
+ return !retCharmap && retIndex;
+}
+FX_BOOL CFX_FontMgrImp::VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode) {
+ if (NULL == pFont) {
+ return FALSE;
+ }
+ FXFT_Face pFace = ((CFX_Font*)pFont->GetDevFont())->GetFace();
+ FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
+ if (0 != FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE)) {
+ return FALSE;
+ }
+ if (0 == FXFT_Get_Char_Index(pFace, wcUnicode)) {
+ FXFT_Set_Charmap(pFace, charmap);
+ return FALSE;
+ }
+ return TRUE;
+}
+IFX_Font* CFX_FontMgrImp::GetFontByLanguage(FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily) {
+ return GetFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles,
+ pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::LoadFont(const uint8_t* pBuffer,
+ int32_t iLength,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount) {
+ void* Hash[2] = {(void*)(uintptr_t)pBuffer, (void*)(uintptr_t)iLength};
+ FX_DWORD dwHash =
+ FX_HashCode_String_GetA((const FX_CHAR*)Hash, 2 * sizeof(void*));
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont(const FX_WCHAR* pszFileName,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount) {
+ CFX_ByteString bsHash;
+ bsHash += CFX_WideString(pszFileName).UTF8Encode();
+ FX_DWORD dwHash =
+ FX_HashCode_String_GetA((const FX_CHAR*)bsHash, bsHash.GetLength());
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ pFontAccess = FX_CreateDefaultFileAccess(pszFileName);
+ m_Hash2FileAccess.SetAt(dwHash, pFontAccess);
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont(IFX_Stream* pFontStream,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount,
+ FX_BOOL bSaveStream) {
+ void* Hash[1] = {(void*)(uintptr_t)pFontStream};
+ FX_DWORD dwHash =
+ FX_HashCode_String_GetA((const FX_CHAR*)Hash, 1 * sizeof(void*));
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont(IFX_FileAccess* pFontAccess,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount,
+ FX_BOOL bWantCache) {
+ FX_DWORD dwHash = 0;
+ IFX_Font* pFont = NULL;
+ if (bWantCache) {
+ CFX_ByteString bsHash;
+ bsHash.Format("%d, %d", (uintptr_t)pFontAccess, iFaceIndex);
+ dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ if (m_FileAccess2IFXFont.Lookup(dwHash, pFont)) {
+ if (NULL != pFont) {
+ if (NULL != pFaceCount) {
+ *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
+ }
+ return pFont->Retain();
+ }
+ }
+ }
+ CFX_Font* pInternalFont = new CFX_Font;
+ IFX_FileRead* pFontStream =
+ pFontAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
+ if (NULL == pFontStream) {
+ delete pInternalFont;
+ return NULL;
+ }
+ if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
+ delete pInternalFont;
+ pFontStream->Release();
+ return NULL;
+ }
+ pFont = IFX_Font::LoadFont(pInternalFont, this, TRUE);
+ if (NULL == pFont) {
+ delete pInternalFont;
+ pFontStream->Release();
+ return NULL;
+ }
+ if (bWantCache) {
+ m_FileAccess2IFXFont.SetAt(dwHash, pFont);
+ }
+ m_IFXFont2FileRead.SetAt(pFont, pFontStream);
+ if (NULL != pFaceCount) {
+ *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
+ }
+ return pFont;
+}
+IFX_Font* CFX_FontMgrImp::LoadFont(const CFX_WideString& wsFaceName,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount) {
+ CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
+ CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
+ if (!pFontMapper)
+ return nullptr;
+ IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
+ if (!pSystemFontInfo)
+ return nullptr;
+ IFX_FileRead* pFontStream =
+ CreateFontStream(pFontMapper, pSystemFontInfo, iFaceIndex);
+ if (!pFontStream)
+ return nullptr;
+ if (!LoadFace(pFontStream, 0)) {
+ pFontStream->Release();
+ return nullptr;
+ }
+ CFX_Font* pInternalFont = new CFX_Font();
+ if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
+ pFontStream->Release();
+ return nullptr;
+ }
+ IFX_Font* pFont = IFX_Font::LoadFont(pInternalFont, this, FALSE);
+ if (!pFont) {
+ pFontStream->Release();
+ return nullptr;
+ }
+ m_IFXFont2FileRead.SetAt(pFont, pFontStream);
+ if (pFaceCount)
+ *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->GetFace()->num_faces;
+ return pFont;
+}
+extern "C" {
+unsigned long _ftStreamRead(FXFT_Stream stream,
+ unsigned long offset,
+ unsigned char* buffer,
+ unsigned long count) {
+ if (count == 0) {
+ return 0;
+ }
+ IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
+ int res = pFile->ReadBlock(buffer, offset, count);
+ if (res) {
+ return count;
+ }
+ return 0;
+}
+void _ftStreamClose(FXFT_Stream stream) {}
+};
+
+FXFT_Face CFX_FontMgrImp::LoadFace(IFX_FileRead* pFontStream,
+ int32_t iFaceIndex) {
+ if (!pFontStream)
+ return nullptr;
+
+ CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
+ pFontMgr->InitFTLibrary();
+ FXFT_Library library = pFontMgr->GetFTLibrary();
+ if (!library)
+ return nullptr;
+
+ FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
+ FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
+ ftStream->base = NULL;
+ ftStream->descriptor.pointer = pFontStream;
+ ftStream->pos = 0;
+ ftStream->size = (unsigned long)pFontStream->GetSize();
+ ftStream->read = _ftStreamRead;
+ ftStream->close = _ftStreamClose;
+
+ FXFT_Open_Args ftArgs;
+ FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args));
+ ftArgs.flags |= FT_OPEN_STREAM;
+ ftArgs.stream = ftStream;
+
+ FXFT_Face pFace = NULL;
+ if (FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) {
+ FX_Free(ftStream);
+ return nullptr;
+ }
+
+ FXFT_Set_Pixel_Sizes(pFace, 0, 64);
+ return pFace;
+}
+IFX_FileRead* CFX_FontMgrImp::CreateFontStream(
+ CFX_FontMapper* pFontMapper,
+ IFX_SystemFontInfo* pSystemFontInfo,
+ FX_DWORD index) {
+ int iExact = 0;
+ void* hFont = pSystemFontInfo->MapFont(
+ 0, 0, FXFONT_DEFAULT_CHARSET, 0, pFontMapper->GetFaceName(index), iExact);
+ if (!hFont)
+ return nullptr;
+ FX_DWORD dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, nullptr, 0);
+ if (dwFileSize == 0)
+ return nullptr;
+ uint8_t* pBuffer = FX_Alloc(uint8_t, dwFileSize + 1);
+ dwFileSize = pSystemFontInfo->GetFontData(hFont, 0, pBuffer, dwFileSize);
+ return new CFX_MemoryStream(pBuffer, dwFileSize, TRUE);
+}
+IFX_FileRead* CFX_FontMgrImp::CreateFontStream(
+ const CFX_ByteString& bsFaceName) {
+ CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
+ CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
+ if (!pFontMapper)
+ return nullptr;
+ IFX_SystemFontInfo* pSystemFontInfo = pFontMapper->GetSystemFontInfo();
+ if (!pSystemFontInfo)
+ return nullptr;
+ pSystemFontInfo->EnumFontList(pFontMapper);
+ for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
+ if (pFontMapper->GetFaceName(i) == bsFaceName)
+ return CreateFontStream(pFontMapper, pSystemFontInfo, i);
+ }
+ return nullptr;
+}
+int32_t CFX_FontMgrImp::MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
+ FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const CFX_WideString& FontName,
+ FX_WCHAR wcUnicode) {
+ MatchedFonts.RemoveAll();
+ CFX_WideString wsNormalizedFontName = FontName;
+ static const int32_t nMax = 0xffff;
+ CFX_FontDescriptor* pFont = NULL;
+ int32_t nCount = m_InstalledFonts.GetSize();
+ for (int32_t i = 0; i < nCount; i++) {
+ pFont = m_InstalledFonts[i];
+ int32_t nPenalty = CalcPenalty(pFont, wCodePage, dwFontStyles,
+ wsNormalizedFontName, wcUnicode);
+ if (nPenalty >= 0xFFFF) {
+ continue;
+ }
+ FX_FontDescriptorInfo FontInfo;
+ FontInfo.pFont = pFont;
+ FontInfo.nPenalty = nPenalty;
+ MatchedFonts.Add(FontInfo);
+ if (MatchedFonts.GetSize() == nMax) {
+ break;
+ }
+ }
+ if (MatchedFonts.GetSize() == 0) {
+ return 0;
+ }
+ CFX_SSortTemplate<FX_FontDescriptorInfo> ssort;
+ ssort.ShellSort(MatchedFonts.GetData(), MatchedFonts.GetSize());
+ return MatchedFonts.GetSize();
+}
+struct FX_BitCodePage {
+ FX_WORD wBit;
+ FX_WORD wCodePage;
+};
+static const FX_BitCodePage g_Bit2CodePage[] = {
+ {0, 1252}, {1, 1250}, {2, 1251}, {3, 1253}, {4, 1254}, {5, 1255},
+ {6, 1256}, {7, 1257}, {8, 1258}, {9, 0}, {10, 0}, {11, 0},
+ {12, 0}, {13, 0}, {14, 0}, {15, 0}, {16, 874}, {17, 932},
+ {18, 936}, {19, 949}, {20, 950}, {21, 1361}, {22, 0}, {23, 0},
+ {24, 0}, {25, 0}, {26, 0}, {27, 0}, {28, 0}, {29, 0},
+ {30, 0}, {31, 0}, {32, 0}, {33, 0}, {34, 0}, {35, 0},
+ {36, 0}, {37, 0}, {38, 0}, {39, 0}, {40, 0}, {41, 0},
+ {42, 0}, {43, 0}, {44, 0}, {45, 0}, {46, 0}, {47, 0},
+ {48, 869}, {49, 866}, {50, 865}, {51, 864}, {52, 863}, {53, 862},
+ {54, 861}, {55, 860}, {56, 857}, {57, 855}, {58, 852}, {59, 775},
+ {60, 737}, {61, 708}, {62, 850}, {63, 437},
+};
+FX_WORD FX_GetCodePageBit(FX_WORD wCodePage) {
+ for (int32_t i = 0; i < sizeof(g_Bit2CodePage) / sizeof(FX_BitCodePage);
+ i++) {
+ if (g_Bit2CodePage[i].wCodePage == wCodePage) {
+ return g_Bit2CodePage[i].wBit;
+ }
+ }
+ return (FX_WORD)-1;
+}
+FX_WORD FX_GetUnicodeBit(FX_WCHAR wcUnicode) {
+ FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wcUnicode);
+ if (NULL == x) {
+ return 999;
+ }
+ return x->wBitField;
+}
+int32_t CFX_FontMgrImp::CalcPenalty(CFX_FontDescriptor* pInstalled,
+ FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const CFX_WideString& FontName,
+ FX_WCHAR wcUnicode) {
+ int32_t nPenalty = 30000;
+ if (0 != FontName.GetLength()) {
+ if (FontName != pInstalled->m_wsFaceName) {
+ int32_t i;
+ for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
+ if (pInstalled->m_wsFamilyNames[i] == FontName) {
+ break;
+ }
+ }
+ if (i == pInstalled->m_wsFamilyNames.GetSize()) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 28000;
+ }
+ } else {
+ nPenalty -= 30000;
+ }
+ if (30000 == nPenalty &&
+ 0 == IsPartName(pInstalled->m_wsFaceName, FontName)) {
+ int32_t i;
+ for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
+ if (0 != IsPartName(pInstalled->m_wsFamilyNames[i], FontName)) {
+ break;
+ }
+ }
+ if (i == pInstalled->m_wsFamilyNames.GetSize()) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 26000;
+ }
+ } else {
+ nPenalty -= 27000;
+ }
+ }
+ FX_DWORD dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
+ if (dwStyleMask & FX_FONTSTYLE_Bold) {
+ nPenalty += 4500;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_FixedPitch) {
+ nPenalty += 10000;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Italic) {
+ nPenalty += 10000;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Serif) {
+ nPenalty += 500;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Symbolic) {
+ nPenalty += 0xFFFF;
+ }
+ if (nPenalty >= 0xFFFF) {
+ return 0xFFFF;
+ }
+ FX_WORD wBit =
+ ((0 == wCodePage || 0xFFFF == wCodePage) ? (FX_WORD)-1
+ : FX_GetCodePageBit(wCodePage));
+ if (wBit != (FX_WORD)-1) {
+ FXSYS_assert(wBit < 64);
+ if (0 == (pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32)))) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 60000;
+ }
+ }
+ wBit =
+ ((0 == wcUnicode || 0xFFFE == wcUnicode) ? (FX_WORD)999
+ : FX_GetUnicodeBit(wcUnicode));
+ if (wBit != (FX_WORD)999) {
+ FXSYS_assert(wBit < 128);
+ if (0 == (pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32)))) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 60000;
+ }
+ }
+ return nPenalty;
+}
+void CFX_FontMgrImp::ClearFontCache() {
+ FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_FontDescriptorInfos* pDescs;
+ m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
+ if (NULL != pDescs) {
+ delete pDescs;
+ }
+ }
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
+ if (NULL != pFont) {
+ pFont->Release();
+ }
+ }
+ pos = m_IFXFont2FileRead.GetStartPosition();
+ while (pos) {
+ IFX_Font* pFont;
+ IFX_FileRead* pFileRead;
+ m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
+ pFileRead->Release();
+ }
+}
+void CFX_FontMgrImp::RemoveFont(IFX_Font* pEFont) {
+ if (NULL == pEFont) {
+ return;
+ }
+ IFX_FileRead* pFileRead;
+ if (m_IFXFont2FileRead.Lookup(pEFont, pFileRead)) {
+ pFileRead->Release();
+ m_IFXFont2FileRead.RemoveKey(pEFont);
+ }
+ FX_POSITION pos;
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pCFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pCFont);
+ if (pCFont == pEFont) {
+ m_FileAccess2IFXFont.RemoveKey(dwHash);
+ break;
+ }
+ }
+ pos = m_Hash2Fonts.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_ArrayTemplate<IFX_Font*>* pFonts;
+ m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
+ if (NULL != pFonts) {
+ for (int32_t i = 0; i < pFonts->GetSize(); i++) {
+ if (pFonts->GetAt(i) == pEFont) {
+ pFonts->SetAt(i, NULL);
+ }
+ }
+ } else {
+ m_Hash2Fonts.RemoveKey(dwHash);
+ }
+ }
+}
+void CFX_FontMgrImp::ReportFace(FXFT_Face pFace,
+ CFX_FontDescriptors& Fonts,
+ IFX_FileAccess* pFontAccess) {
+ if (0 == (pFace->face_flags & FT_FACE_FLAG_SCALABLE)) {
+ return;
+ }
+ CFX_FontDescriptor* pFont = new CFX_FontDescriptor;
+ pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0;
+ pFont->m_dwFontStyles |= FXFT_Is_Face_Italic(pFace) ? FX_FONTSTYLE_Italic : 0;
+ pFont->m_dwFontStyles |= GetFlags(pFace);
+ CFX_WordArray Charsets;
+ GetCharsets(pFace, Charsets);
+ GetUSBCSB(pFace, pFont->m_dwUsb, pFont->m_dwCsb);
+ unsigned long nLength = 0;
+ FT_ULong dwTag;
+ uint8_t* pTable = NULL;
+ FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
+ unsigned int error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, NULL, &nLength);
+ if (0 == error && 0 != nLength) {
+ pTable = FX_Alloc(uint8_t, nLength);
+ error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, pTable, NULL);
+ if (0 != error) {
+ FX_Free(pTable);
+ pTable = NULL;
+ }
+ }
+ GetNames(pTable, pFont->m_wsFamilyNames);
+ if (NULL != pTable) {
+ FX_Free(pTable);
+ }
+ pFont->m_wsFamilyNames.Add(CFX_ByteString(pFace->family_name).UTF8Decode());
+ pFont->m_wsFaceName =
+ CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace));
+ pFont->m_nFaceIndex = pFace->face_index;
+ if (pFontAccess)
+ pFont->m_pFileAccess = pFontAccess->Retain();
+ else
+ pFont->m_pFileAccess = nullptr;
+ Fonts.Add(pFont);
+}
+void CFX_FontMgrImp::ReportFaces(IFX_FileRead* pFontStream) {
+ int32_t index = 0;
+ int32_t num_faces = 0;
+ do {
+ FXFT_Face pFace = LoadFace(pFontStream, index++);
+ if (!pFace)
+ continue;
+ // All faces keep number of faces. It can be retrieved from any one face.
+ if (!num_faces)
+ num_faces = pFace->num_faces;
+ ReportFace(pFace, m_InstalledFonts, nullptr);
+ if (FXFT_Get_Face_External_Stream(pFace))
+ FXFT_Clear_Face_External_Stream(pFace);
+ FXFT_Done_Face(pFace);
+ } while (index < num_faces);
+}
+FX_DWORD CFX_FontMgrImp::GetFlags(FXFT_Face pFace) {
+ FX_DWORD flag = 0;
+ if (FT_IS_FIXED_WIDTH(pFace)) {
+ flag |= FX_FONTSTYLE_FixedPitch;
+ }
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (!pOS2) {
+ return flag;
+ }
+ if (pOS2->ulCodePageRange1 & (1 << 31)) {
+ flag |= FX_FONTSTYLE_Symbolic;
+ }
+ if (pOS2->panose[0] == 2) {
+ uint8_t uSerif = pOS2->panose[1];
+ if ((uSerif > 1 && uSerif < 10) || uSerif > 13) {
+ flag |= FX_FONTSTYLE_Serif;
+ }
+ }
+ return flag;
+}
+#define GetUInt8(p) ((uint8_t)((p)[0]))
+#define GetUInt16(p) ((uint16_t)((p)[0] << 8 | (p)[1]))
+#define GetUInt32(p) \
+ ((uint32_t)((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3]))
+void CFX_FontMgrImp::GetNames(const uint8_t* name_table,
+ CFX_WideStringArray& Names) {
+ if (NULL == name_table) {
+ return;
+ }
+ uint8_t* lpTable = (uint8_t*)name_table;
+ CFX_WideString wsFamily;
+ uint8_t* sp = lpTable + 2;
+ uint8_t* lpNameRecord = lpTable + 6;
+ uint16_t nNameCount = GetUInt16(sp);
+ uint8_t* lpStr = lpTable + GetUInt16(sp + 2);
+ for (uint16_t j = 0; j < nNameCount; j++) {
+ uint16_t nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
+ if (nNameID != 1) {
+ continue;
+ }
+ uint16_t nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
+ uint16_t nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
+ uint16_t nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
+ wsFamily.Empty();
+ if (nPlatformID != 1) {
+ for (uint16_t k = 0; k < nNameLength / 2; k++) {
+ FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
+ wsFamily += wcTemp;
+ }
+ Names.Add(wsFamily);
+ } else {
+ for (uint16_t k = 0; k < nNameLength; k++) {
+ FX_WCHAR wcTemp = GetUInt8(lpStr + nNameOffset + k);
+ wsFamily += wcTemp;
+ }
+ Names.Add(wsFamily);
+ }
+ }
+}
+#undef GetUInt8
+#undef GetUInt16
+#undef GetUInt32
+struct FX_BIT2CHARSET {
+ FX_WORD wBit;
+ FX_WORD wCharset;
+};
+FX_BIT2CHARSET g_FX_Bit2Charset1[16] = {
+ {1 << 0, FX_CHARSET_ANSI},
+ {1 << 1, FX_CHARSET_MSWin_EasterEuropean},
+ {1 << 2, FX_CHARSET_MSWin_Cyrillic},
+ {1 << 3, FX_CHARSET_MSWin_Greek},
+ {1 << 4, FX_CHARSET_MSWin_Turkish},
+ {1 << 5, FX_CHARSET_MSWin_Hebrew},
+ {1 << 6, FX_CHARSET_MSWin_Arabic},
+ {1 << 7, FX_CHARSET_MSWin_Baltic},
+ {1 << 8, FX_CHARSET_MSWin_Vietnamese},
+ {1 << 9, FX_CHARSET_Default},
+ {1 << 10, FX_CHARSET_Default},
+ {1 << 11, FX_CHARSET_Default},
+ {1 << 12, FX_CHARSET_Default},
+ {1 << 13, FX_CHARSET_Default},
+ {1 << 14, FX_CHARSET_Default},
+ {1 << 15, FX_CHARSET_Default},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset2[16] = {
+ {1 << 0, FX_CHARSET_Thai},
+ {1 << 1, FX_CHARSET_ShiftJIS},
+ {1 << 2, FX_CHARSET_ChineseSimplified},
+ {1 << 3, FX_CHARSET_Korean},
+ {1 << 4, FX_CHARSET_ChineseTriditional},
+ {1 << 5, FX_CHARSET_Johab},
+ {1 << 6, FX_CHARSET_Default},
+ {1 << 7, FX_CHARSET_Default},
+ {1 << 8, FX_CHARSET_Default},
+ {1 << 9, FX_CHARSET_Default},
+ {1 << 10, FX_CHARSET_Default},
+ {1 << 11, FX_CHARSET_Default},
+ {1 << 12, FX_CHARSET_Default},
+ {1 << 13, FX_CHARSET_Default},
+ {1 << 14, FX_CHARSET_OEM},
+ {1 << 15, FX_CHARSET_Symbol},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset3[16] = {
+ {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
+ {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
+ {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
+ {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
+ {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
+ {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
+ {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
+ {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_Default},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset4[16] = {
+ {1 << 0, FX_CHARSET_Default}, {1 << 1, FX_CHARSET_Default},
+ {1 << 2, FX_CHARSET_Default}, {1 << 3, FX_CHARSET_Default},
+ {1 << 4, FX_CHARSET_Default}, {1 << 5, FX_CHARSET_Default},
+ {1 << 6, FX_CHARSET_Default}, {1 << 7, FX_CHARSET_Default},
+ {1 << 8, FX_CHARSET_Default}, {1 << 9, FX_CHARSET_Default},
+ {1 << 10, FX_CHARSET_Default}, {1 << 11, FX_CHARSET_Default},
+ {1 << 12, FX_CHARSET_Default}, {1 << 13, FX_CHARSET_Default},
+ {1 << 14, FX_CHARSET_Default}, {1 << 15, FX_CHARSET_US},
+};
+#define CODEPAGERANGE_IMPLEMENT(n) \
+ for (int32_t i = 0; i < 16; i++) { \
+ if ((a##n & g_FX_Bit2Charset##n[i].wBit) != 0) { \
+ Charsets.Add(g_FX_Bit2Charset##n[i].wCharset); \
+ } \
+ }
+void CFX_FontMgrImp::GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets) {
+ Charsets.RemoveAll();
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (NULL != pOS2) {
+ FX_WORD a1, a2, a3, a4;
+ a1 = pOS2->ulCodePageRange1 & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(1);
+ a2 = (pOS2->ulCodePageRange1 >> 16) & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(2);
+ a3 = pOS2->ulCodePageRange2 & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(3);
+ a4 = (pOS2->ulCodePageRange2 >> 16) & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(4);
+ } else {
+ Charsets.Add(FX_CHARSET_Default);
+ }
+}
+#undef CODEPAGERANGE_IMPLEMENT
+void CFX_FontMgrImp::GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB) {
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (NULL != pOS2) {
+ USB[0] = pOS2->ulUnicodeRange1;
+ USB[1] = pOS2->ulUnicodeRange2;
+ USB[2] = pOS2->ulUnicodeRange3;
+ USB[3] = pOS2->ulUnicodeRange4;
+ CSB[0] = pOS2->ulCodePageRange1;
+ CSB[1] = pOS2->ulCodePageRange2;
+ } else {
+ USB[0] = 0;
+ USB[1] = 0;
+ USB[2] = 0;
+ USB[3] = 0;
+ CSB[0] = 0;
+ CSB[1] = 0;
+ }
+}
+int32_t CFX_FontMgrImp::IsPartName(const CFX_WideString& Name1,
+ const CFX_WideString& Name2) {
+ if (Name1.Find((const FX_WCHAR*)Name2) != -1) {
+ return 1;
+ }
+ return 0;
+}
+#endif
diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.h b/xfa/src/fgas/src/font/fx_stdfontmgr.h
index 7ce7b5064f..fe14ad7984 100644
--- a/xfa/src/fgas/src/font/fx_stdfontmgr.h
+++ b/xfa/src/fgas/src/font/fx_stdfontmgr.h
@@ -1,234 +1,234 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_FONTMGR_IMP
-#define _FX_FONTMGR_IMP
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-int32_t FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles);
-FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams,
- const CFX_FontDescriptors& fonts,
- void* pUserData);
-class CFX_StdFontMgrImp : public IFX_FontMgr {
- public:
- CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator,
- FX_LPMatchFont pMatcher,
- void* pUserData);
- ~CFX_StdFontMgrImp();
- virtual void Release() { delete this; }
- virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByCharset(uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* LoadFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage = 0xFFFF);
- virtual IFX_Font* LoadFont(const uint8_t* pBuffer, int32_t iLength);
- virtual IFX_Font* LoadFont(const FX_WCHAR* pszFileName);
- virtual IFX_Font* LoadFont(IFX_Stream* pFontStream,
- const FX_WCHAR* pszFontAlias = NULL,
- FX_DWORD dwFontStyles = 0,
- FX_WORD wCodePage = 0,
- FX_BOOL bSaveStream = FALSE);
- virtual IFX_Font* LoadFont(IFX_Font* pSrcFont,
- FX_DWORD dwFontStyles,
- FX_WORD wCodePage = 0xFFFF);
- virtual void ClearFontCache();
- virtual void RemoveFont(IFX_Font* pFont);
-
- protected:
- FX_LPMatchFont m_pMatcher;
- FX_LPEnumAllFonts m_pEnumerator;
- CFX_FontDescriptors m_FontFaces;
- CFX_PtrArray m_Fonts;
- CFX_MapPtrToPtr m_CPFonts;
- CFX_MapPtrToPtr m_FamilyFonts;
- CFX_MapPtrToPtr m_UnicodeFonts;
- CFX_MapPtrToPtr m_BufferFonts;
- CFX_MapPtrToPtr m_FileFonts;
- CFX_MapPtrToPtr m_StreamFonts;
- CFX_MapPtrToPtr m_DeriveFonts;
- void* m_pUserData;
- void RemoveFont(CFX_MapPtrToPtr& fontMap, IFX_Font* pFont);
- FX_LPCFONTDESCRIPTOR FindFont(const FX_WCHAR* pszFontFamily,
- FX_DWORD dwFontStyles,
- FX_DWORD dwMatchFlags,
- FX_WORD wCodePage,
- FX_DWORD dwUSB = 999,
- FX_WCHAR wUnicode = 0);
- IFX_Font* GetFont(FX_LPCFONTDESCRIPTOR pFD, FX_DWORD dwFontStyles);
-};
-FX_DWORD FX_GetGdiFontStyles(const LOGFONTW& lf);
-#else
-class CFX_FontDescriptor {
- public:
- CFX_FontDescriptor()
- : m_pFileAccess(NULL), m_nFaceIndex(0), m_dwFontStyles(0) {
- m_dwUsb[0] = m_dwUsb[1] = m_dwUsb[2] = m_dwUsb[3] = 0;
- m_dwCsb[0] = m_dwCsb[1] = 0;
- }
- ~CFX_FontDescriptor() {
- if (NULL != m_pFileAccess) {
- m_pFileAccess->Release();
- }
- }
- IFX_FileAccess* m_pFileAccess;
- int32_t m_nFaceIndex;
- CFX_WideString m_wsFaceName;
- CFX_WideStringArray m_wsFamilyNames;
- FX_DWORD m_dwFontStyles;
- FX_DWORD m_dwUsb[4];
- FX_DWORD m_dwCsb[2];
-};
-typedef CFX_ArrayTemplate<CFX_FontDescriptor*> CFX_FontDescriptors;
-struct FX_FontDescriptorInfo {
- public:
- CFX_FontDescriptor* pFont;
- int32_t nPenalty;
- FX_BOOL operator>(const FX_FontDescriptorInfo& x) {
- return this->nPenalty > x.nPenalty;
- };
- FX_BOOL operator<(const FX_FontDescriptorInfo& x) {
- return this->nPenalty < x.nPenalty;
- };
- FX_BOOL operator==(const FX_FontDescriptorInfo& x) {
- return this->nPenalty == x.nPenalty;
- };
-};
-typedef CFX_ArrayTemplate<FX_FontDescriptorInfo> CFX_FontDescriptorInfos;
-struct FX_HandleParentPath {
- FX_HandleParentPath() {}
- FX_HandleParentPath(const FX_HandleParentPath& x) {
- pFileHandle = x.pFileHandle;
- bsParentPath = x.bsParentPath;
- }
- void* pFileHandle;
- CFX_ByteString bsParentPath;
-};
-class CFX_FontSourceEnum_File : public IFX_FontSourceEnum {
- public:
- CFX_FontSourceEnum_File();
- virtual void Release() { delete this; };
- virtual FX_POSITION GetStartPosition(void* pUserData = NULL);
- virtual IFX_FileAccess* GetNext(FX_POSITION& pos, void* pUserData = NULL);
-
- private:
- CFX_ByteString GetNextFile();
- CFX_WideString m_wsNext;
- CFX_ObjectArray<FX_HandleParentPath> m_FolderQueue;
- CFX_ByteStringArray m_FolderPaths;
-};
-typedef CFX_MapPtrTemplate<FX_DWORD, IFX_FileAccess*> CFX_HashFileMap;
-typedef CFX_MapPtrTemplate<FX_DWORD, IFX_Font*> CFX_HashFontMap;
-typedef CFX_MapPtrTemplate<FX_DWORD, CFX_FontDescriptorInfos*>
- CFX_HashFontDescsMap;
-typedef CFX_MapPtrTemplate<FX_DWORD, CFX_ArrayTemplate<IFX_Font*>*>
- CFX_HashFontsMap;
-typedef CFX_MapPtrTemplate<FX_WCHAR, IFX_Font*> CFX_UnicodeFontMap;
-typedef CFX_MapPtrTemplate<IFX_FileAccess*, CFX_ArrayTemplate<IFX_Font*>*>
- CFX_FileFontMap;
-typedef CFX_MapPtrTemplate<IFX_Font*, IFX_FileRead*> CFX_FonStreamtMap;
-class CFX_FontMgrImp : public IFX_FontMgr {
- public:
- CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum,
- IFX_FontMgrDelegate* pDelegate = NULL,
- void* pUserData = NULL);
- virtual void Release();
- virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByCharset(uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetFontByCharset(uint8_t nCharset,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage,
- FX_DWORD dwFontStyles,
- const FX_WCHAR* pszFontFamily = NULL);
- virtual IFX_Font* LoadFont(const uint8_t* pBuffer,
- int32_t iLength,
- int32_t iFaceIndex,
- int32_t* pFaceCount);
- virtual IFX_Font* LoadFont(const FX_WCHAR* pszFileName,
- int32_t iFaceIndex,
- int32_t* pFaceCount);
- virtual IFX_Font* LoadFont(IFX_Stream* pFontStream,
- int32_t iFaceIndex,
- int32_t* pFaceCount,
- FX_BOOL bSaveStream = FALSE);
- virtual IFX_Font* LoadFont(const CFX_WideString& wsFaceName,
- int32_t iFaceIndex,
- int32_t* pFaceCount);
- virtual void ClearFontCache();
- virtual void RemoveFont(IFX_Font* pFont);
- FX_BOOL EnumFonts();
- FX_BOOL EnumFontsFromFontMapper();
- FX_BOOL EnumFontsFromFiles();
-
- protected:
- void ReportFace(FXFT_Face pFace,
- CFX_FontDescriptors& Fonts,
- IFX_FileAccess* pFontAccess);
- void ReportFaces(IFX_FileRead* pFontStream);
- void GetNames(const uint8_t* name_table, CFX_WideStringArray& Names);
- void GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets);
- void GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB);
- FX_DWORD GetFlags(FXFT_Face pFace);
- CFX_FontDescriptors m_InstalledFonts;
- FX_BOOL VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode);
- FX_BOOL VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode);
- int32_t IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2);
- int32_t MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
- FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const CFX_WideString& FontName,
- FX_WCHAR wcUnicode = 0xFFFE);
- int32_t CalcPenalty(CFX_FontDescriptor* pInstalled,
- FX_WORD wCodePage,
- FX_DWORD dwFontStyles,
- const CFX_WideString& FontName,
- FX_WCHAR wcUnicode = 0xFFFE);
- IFX_Font* LoadFont(IFX_FileAccess* pFontAccess,
- int32_t iFaceIndex,
- int32_t* pFaceCount,
- FX_BOOL bWantCache = FALSE);
- FXFT_Face LoadFace(IFX_FileRead* pFontStream, int32_t iFaceIndex);
- IFX_FileRead* CreateFontStream(CFX_FontMapper* pFontMapper,
- IFX_SystemFontInfo* pSystemFontInfo,
- FX_DWORD index);
- IFX_FileRead* CreateFontStream(const CFX_ByteString& bsFaceName);
- CFX_HashFontDescsMap m_Hash2CandidateList;
- CFX_HashFontsMap m_Hash2Fonts;
- CFX_HashFileMap m_Hash2FileAccess;
- CFX_HashFontMap m_FileAccess2IFXFont;
- CFX_FonStreamtMap m_IFXFont2FileRead;
- CFX_UnicodeFontMap m_FailedUnicodes2NULL;
- IFX_FontSourceEnum* m_pFontSource;
- IFX_FontMgrDelegate* m_pDelegate;
- void* m_pUserData;
-};
-#endif
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_FONTMGR_IMP
+#define _FX_FONTMGR_IMP
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+int32_t FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles);
+FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams,
+ const CFX_FontDescriptors& fonts,
+ void* pUserData);
+class CFX_StdFontMgrImp : public IFX_FontMgr {
+ public:
+ CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator,
+ FX_LPMatchFont pMatcher,
+ void* pUserData);
+ ~CFX_StdFontMgrImp();
+ virtual void Release() { delete this; }
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByCharset(uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* LoadFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage = 0xFFFF);
+ virtual IFX_Font* LoadFont(const uint8_t* pBuffer, int32_t iLength);
+ virtual IFX_Font* LoadFont(const FX_WCHAR* pszFileName);
+ virtual IFX_Font* LoadFont(IFX_Stream* pFontStream,
+ const FX_WCHAR* pszFontAlias = NULL,
+ FX_DWORD dwFontStyles = 0,
+ FX_WORD wCodePage = 0,
+ FX_BOOL bSaveStream = FALSE);
+ virtual IFX_Font* LoadFont(IFX_Font* pSrcFont,
+ FX_DWORD dwFontStyles,
+ FX_WORD wCodePage = 0xFFFF);
+ virtual void ClearFontCache();
+ virtual void RemoveFont(IFX_Font* pFont);
+
+ protected:
+ FX_LPMatchFont m_pMatcher;
+ FX_LPEnumAllFonts m_pEnumerator;
+ CFX_FontDescriptors m_FontFaces;
+ CFX_PtrArray m_Fonts;
+ CFX_MapPtrToPtr m_CPFonts;
+ CFX_MapPtrToPtr m_FamilyFonts;
+ CFX_MapPtrToPtr m_UnicodeFonts;
+ CFX_MapPtrToPtr m_BufferFonts;
+ CFX_MapPtrToPtr m_FileFonts;
+ CFX_MapPtrToPtr m_StreamFonts;
+ CFX_MapPtrToPtr m_DeriveFonts;
+ void* m_pUserData;
+ void RemoveFont(CFX_MapPtrToPtr& fontMap, IFX_Font* pFont);
+ FX_LPCFONTDESCRIPTOR FindFont(const FX_WCHAR* pszFontFamily,
+ FX_DWORD dwFontStyles,
+ FX_DWORD dwMatchFlags,
+ FX_WORD wCodePage,
+ FX_DWORD dwUSB = 999,
+ FX_WCHAR wUnicode = 0);
+ IFX_Font* GetFont(FX_LPCFONTDESCRIPTOR pFD, FX_DWORD dwFontStyles);
+};
+FX_DWORD FX_GetGdiFontStyles(const LOGFONTW& lf);
+#else
+class CFX_FontDescriptor {
+ public:
+ CFX_FontDescriptor()
+ : m_pFileAccess(NULL), m_nFaceIndex(0), m_dwFontStyles(0) {
+ m_dwUsb[0] = m_dwUsb[1] = m_dwUsb[2] = m_dwUsb[3] = 0;
+ m_dwCsb[0] = m_dwCsb[1] = 0;
+ }
+ ~CFX_FontDescriptor() {
+ if (NULL != m_pFileAccess) {
+ m_pFileAccess->Release();
+ }
+ }
+ IFX_FileAccess* m_pFileAccess;
+ int32_t m_nFaceIndex;
+ CFX_WideString m_wsFaceName;
+ CFX_WideStringArray m_wsFamilyNames;
+ FX_DWORD m_dwFontStyles;
+ FX_DWORD m_dwUsb[4];
+ FX_DWORD m_dwCsb[2];
+};
+typedef CFX_ArrayTemplate<CFX_FontDescriptor*> CFX_FontDescriptors;
+struct FX_FontDescriptorInfo {
+ public:
+ CFX_FontDescriptor* pFont;
+ int32_t nPenalty;
+ FX_BOOL operator>(const FX_FontDescriptorInfo& x) {
+ return this->nPenalty > x.nPenalty;
+ };
+ FX_BOOL operator<(const FX_FontDescriptorInfo& x) {
+ return this->nPenalty < x.nPenalty;
+ };
+ FX_BOOL operator==(const FX_FontDescriptorInfo& x) {
+ return this->nPenalty == x.nPenalty;
+ };
+};
+typedef CFX_ArrayTemplate<FX_FontDescriptorInfo> CFX_FontDescriptorInfos;
+struct FX_HandleParentPath {
+ FX_HandleParentPath() {}
+ FX_HandleParentPath(const FX_HandleParentPath& x) {
+ pFileHandle = x.pFileHandle;
+ bsParentPath = x.bsParentPath;
+ }
+ void* pFileHandle;
+ CFX_ByteString bsParentPath;
+};
+class CFX_FontSourceEnum_File : public IFX_FontSourceEnum {
+ public:
+ CFX_FontSourceEnum_File();
+ virtual void Release() { delete this; };
+ virtual FX_POSITION GetStartPosition(void* pUserData = NULL);
+ virtual IFX_FileAccess* GetNext(FX_POSITION& pos, void* pUserData = NULL);
+
+ private:
+ CFX_ByteString GetNextFile();
+ CFX_WideString m_wsNext;
+ CFX_ObjectArray<FX_HandleParentPath> m_FolderQueue;
+ CFX_ByteStringArray m_FolderPaths;
+};
+typedef CFX_MapPtrTemplate<FX_DWORD, IFX_FileAccess*> CFX_HashFileMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, IFX_Font*> CFX_HashFontMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, CFX_FontDescriptorInfos*>
+ CFX_HashFontDescsMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, CFX_ArrayTemplate<IFX_Font*>*>
+ CFX_HashFontsMap;
+typedef CFX_MapPtrTemplate<FX_WCHAR, IFX_Font*> CFX_UnicodeFontMap;
+typedef CFX_MapPtrTemplate<IFX_FileAccess*, CFX_ArrayTemplate<IFX_Font*>*>
+ CFX_FileFontMap;
+typedef CFX_MapPtrTemplate<IFX_Font*, IFX_FileRead*> CFX_FonStreamtMap;
+class CFX_FontMgrImp : public IFX_FontMgr {
+ public:
+ CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum,
+ IFX_FontMgrDelegate* pDelegate = NULL,
+ void* pUserData = NULL);
+ virtual void Release();
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByCharset(uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByCharset(uint8_t nCharset,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage,
+ FX_DWORD dwFontStyles,
+ const FX_WCHAR* pszFontFamily = NULL);
+ virtual IFX_Font* LoadFont(const uint8_t* pBuffer,
+ int32_t iLength,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount);
+ virtual IFX_Font* LoadFont(const FX_WCHAR* pszFileName,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount);
+ virtual IFX_Font* LoadFont(IFX_Stream* pFontStream,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount,
+ FX_BOOL bSaveStream = FALSE);
+ virtual IFX_Font* LoadFont(const CFX_WideString& wsFaceName,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount);
+ virtual void ClearFontCache();
+ virtual void RemoveFont(IFX_Font* pFont);
+ FX_BOOL EnumFonts();
+ FX_BOOL EnumFontsFromFontMapper();
+ FX_BOOL EnumFontsFromFiles();
+
+ protected:
+ void ReportFace(FXFT_Face pFace,
+ CFX_FontDescriptors& Fonts,
+ IFX_FileAccess* pFontAccess);
+ void ReportFaces(IFX_FileRead* pFontStream);
+ void GetNames(const uint8_t* name_table, CFX_WideStringArray& Names);
+ void GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets);
+ void GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB);
+ FX_DWORD GetFlags(FXFT_Face pFace);
+ CFX_FontDescriptors m_InstalledFonts;
+ FX_BOOL VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode);
+ FX_BOOL VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode);
+ int32_t IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2);
+ int32_t MatchFonts(CFX_FontDescriptorInfos& MatchedFonts,
+ FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const CFX_WideString& FontName,
+ FX_WCHAR wcUnicode = 0xFFFE);
+ int32_t CalcPenalty(CFX_FontDescriptor* pInstalled,
+ FX_WORD wCodePage,
+ FX_DWORD dwFontStyles,
+ const CFX_WideString& FontName,
+ FX_WCHAR wcUnicode = 0xFFFE);
+ IFX_Font* LoadFont(IFX_FileAccess* pFontAccess,
+ int32_t iFaceIndex,
+ int32_t* pFaceCount,
+ FX_BOOL bWantCache = FALSE);
+ FXFT_Face LoadFace(IFX_FileRead* pFontStream, int32_t iFaceIndex);
+ IFX_FileRead* CreateFontStream(CFX_FontMapper* pFontMapper,
+ IFX_SystemFontInfo* pSystemFontInfo,
+ FX_DWORD index);
+ IFX_FileRead* CreateFontStream(const CFX_ByteString& bsFaceName);
+ CFX_HashFontDescsMap m_Hash2CandidateList;
+ CFX_HashFontsMap m_Hash2Fonts;
+ CFX_HashFileMap m_Hash2FileAccess;
+ CFX_HashFontMap m_FileAccess2IFXFont;
+ CFX_FonStreamtMap m_IFXFont2FileRead;
+ CFX_UnicodeFontMap m_FailedUnicodes2NULL;
+ IFX_FontSourceEnum* m_pFontSource;
+ IFX_FontMgrDelegate* m_pDelegate;
+ void* m_pUserData;
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_linebreak.cpp b/xfa/src/fgas/src/layout/fx_linebreak.cpp
index 2757904250..e89dfb7486 100644
--- a/xfa/src/fgas/src/layout/fx_linebreak.cpp
+++ b/xfa/src/fgas/src/layout/fx_linebreak.cpp
@@ -1,318 +1,318 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-
-const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32] = {
- {FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBPB, FX_LBPB, FX_LBPB, FX_LBCP, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBPB, FX_LBPB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBPB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBIB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBPB,
- FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBPB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
- FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
- FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
- FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
- {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
- FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
-};
-
-void FX_GetLineBreakPositions(const FX_WCHAR* pwsText,
- FX_LINEBREAKTYPE* pBrkType,
- int32_t iLength) {
- if (iLength < 2) {
- return;
- }
- FX_DWORD dwCur, dwNext;
- FX_WCHAR wch;
- wch = *pwsText++;
- dwCur = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
- iLength--;
- for (int32_t i = 0; i < iLength; i++) {
- wch = *pwsText++;
- dwNext = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
- if (dwNext == FX_CBP_SP) {
- pBrkType[i] = FX_LBT_PROHIBITED_BRK;
- } else {
- pBrkType[i] = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (dwCur << 5) + dwNext);
- }
- dwCur = dwNext;
- }
- pBrkType[iLength] = FX_LBT_INDIRECT_BRK;
-}
-void FX_GetLineBreakPositions(const FX_WCHAR* pwsText,
- int32_t iLength,
- CFX_Int32MassArray& bp) {
- if (iLength < 2) {
- return;
- }
- FX_LINEBREAKTYPE eType;
- FX_DWORD dwCur, dwNext;
- FX_WCHAR wch;
- wch = *pwsText++;
- dwCur = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
- iLength--;
- for (int32_t i = 0; i < iLength; i++) {
- wch = *pwsText++;
- dwNext = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
- if (dwNext == FX_CBP_SP) {
- eType = FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (dwCur << 5) + dwNext);
- }
- if (eType == FX_LBT_DIRECT_BRK) {
- bp.Add(i);
- }
- dwCur = dwNext;
- }
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+
+const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32] = {
+ {FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBPB, FX_LBPB, FX_LBPB, FX_LBCP, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBPB, FX_LBPB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBPB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBIB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBPB,
+ FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBPB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB,
+ FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB,
+ FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB,
+ FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN,
+ FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+};
+
+void FX_GetLineBreakPositions(const FX_WCHAR* pwsText,
+ FX_LINEBREAKTYPE* pBrkType,
+ int32_t iLength) {
+ if (iLength < 2) {
+ return;
+ }
+ FX_DWORD dwCur, dwNext;
+ FX_WCHAR wch;
+ wch = *pwsText++;
+ dwCur = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
+ iLength--;
+ for (int32_t i = 0; i < iLength; i++) {
+ wch = *pwsText++;
+ dwNext = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
+ if (dwNext == FX_CBP_SP) {
+ pBrkType[i] = FX_LBT_PROHIBITED_BRK;
+ } else {
+ pBrkType[i] = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (dwCur << 5) + dwNext);
+ }
+ dwCur = dwNext;
+ }
+ pBrkType[iLength] = FX_LBT_INDIRECT_BRK;
+}
+void FX_GetLineBreakPositions(const FX_WCHAR* pwsText,
+ int32_t iLength,
+ CFX_Int32MassArray& bp) {
+ if (iLength < 2) {
+ return;
+ }
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD dwCur, dwNext;
+ FX_WCHAR wch;
+ wch = *pwsText++;
+ dwCur = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
+ iLength--;
+ for (int32_t i = 0; i < iLength; i++) {
+ wch = *pwsText++;
+ dwNext = kTextLayoutCodeProperties[(FX_WORD)wch] & 0x003F;
+ if (dwNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (dwCur << 5) + dwNext);
+ }
+ if (eType == FX_LBT_DIRECT_BRK) {
+ bp.Add(i);
+ }
+ dwCur = dwNext;
+ }
+}
diff --git a/xfa/src/fgas/src/layout/fx_rtfbreak.cpp b/xfa/src/fgas/src/layout/fx_rtfbreak.cpp
index 649d9bac37..8b28395119 100644
--- a/xfa/src/fgas/src/layout/fx_rtfbreak.cpp
+++ b/xfa/src/fgas/src/layout/fx_rtfbreak.cpp
@@ -1,1525 +1,1525 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/include/fx_lbk.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "xfa/src/fgas/src/layout/fx_unicode.h"
-#include "xfa/src/fgas/src/layout/fx_rtfbreak.h"
-
-IFX_RTFBreak* IFX_RTFBreak::Create(FX_DWORD dwPolicies) {
- return new CFX_RTFBreak(dwPolicies);
-}
-CFX_RTFBreak::CFX_RTFBreak(FX_DWORD dwPolicies)
- : m_dwPolicies(dwPolicies),
- m_pArabicChar(NULL),
- m_iBoundaryStart(0),
- m_iBoundaryEnd(2000000),
- m_dwLayoutStyles(0),
- m_bPagination(FALSE),
- m_bVertical(FALSE),
- m_bSingleLine(FALSE),
- m_bCharCode(FALSE),
- m_pFont(NULL),
- m_iFontHeight(240),
- m_iFontSize(240),
- m_iTabWidth(720000),
- m_PositionedTabs(),
- m_bOrphanLine(FALSE),
- m_wDefChar(0xFEFF),
- m_iDefChar(0),
- m_wLineBreakChar(L'\n'),
- m_iHorizontalScale(100),
- m_iVerticalScale(100),
- m_iLineRotation(0),
- m_iCharRotation(0),
- m_iRotation(0),
- m_iCharSpace(0),
- m_bWordSpace(FALSE),
- m_iWordSpace(0),
- m_bRTL(FALSE),
- m_iAlignment(FX_RTFLINEALIGNMENT_Left),
- m_pUserData(NULL),
- m_dwCharType(0),
- m_dwIdentity(0),
- m_RTFLine1(),
- m_RTFLine2(),
- m_pCurLine(NULL),
- m_iReady(0),
- m_iTolerance(0) {
- m_pArabicChar = IFX_ArabicChar::Create();
- m_pCurLine = &m_RTFLine1;
-}
-CFX_RTFBreak::~CFX_RTFBreak() {
- Reset();
- m_PositionedTabs.RemoveAll();
- m_pArabicChar->Release();
- if (m_pUserData != NULL) {
- m_pUserData->Release();
- }
-}
-void CFX_RTFBreak::SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) {
- if (fLineStart > fLineEnd)
- return;
- m_iBoundaryStart = FXSYS_round(fLineStart * 20000.0f);
- m_iBoundaryEnd = FXSYS_round(fLineEnd * 20000.0f);
- m_pCurLine->m_iStart = std::min(m_pCurLine->m_iStart, m_iBoundaryEnd);
- m_pCurLine->m_iStart = std::max(m_pCurLine->m_iStart, m_iBoundaryStart);
-}
-void CFX_RTFBreak::SetLineStartPos(FX_FLOAT fLinePos) {
- int32_t iLinePos = FXSYS_round(fLinePos * 20000.0f);
- iLinePos = std::min(iLinePos, m_iBoundaryEnd);
- iLinePos = std::max(iLinePos, m_iBoundaryStart);
- m_pCurLine->m_iStart = iLinePos;
-}
-void CFX_RTFBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles) {
- if (m_dwLayoutStyles == dwLayoutStyles) {
- return;
- }
- SetBreakStatus();
- m_dwLayoutStyles = dwLayoutStyles;
- m_bPagination = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination) != 0;
- m_bVertical = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
- m_bSingleLine = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
- m_bCharCode = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
- m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
- m_iRotation = m_iLineRotation + m_iCharRotation;
- m_iRotation %= 4;
-}
-void CFX_RTFBreak::SetFont(IFX_Font* pFont) {
- if (pFont == NULL) {
- return;
- }
- if (m_pFont == pFont) {
- return;
- }
- SetBreakStatus();
- m_pFont = pFont;
- m_iDefChar = 0;
- if (m_pFont != NULL) {
- m_iFontHeight = m_iFontSize;
- if (m_wDefChar != 0xFEFF) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- m_iDefChar *= m_iFontSize;
- }
- }
-}
-void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize) {
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- if (m_iFontSize == iFontSize) {
- return;
- }
- SetBreakStatus();
- m_iFontSize = iFontSize;
- m_iDefChar = 0;
- if (m_pFont != NULL) {
- m_iFontHeight = m_iFontSize;
- if (m_wDefChar != 0xFEFF) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- m_iDefChar *= m_iFontSize;
- }
- }
-}
-void CFX_RTFBreak::SetTabWidth(FX_FLOAT fTabWidth) {
- m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
-}
-void CFX_RTFBreak::AddPositionedTab(FX_FLOAT fTabPos) {
- int32_t iLineEnd = m_iBoundaryEnd;
- int32_t iTabPos = FXSYS_round(fTabPos * 20000.0f) + m_iBoundaryStart;
- if (iTabPos > iLineEnd) {
- iTabPos = iLineEnd;
- }
- if (m_PositionedTabs.Find(iTabPos, 0) > -1) {
- return;
- }
- int32_t iCount = m_PositionedTabs.GetSize();
- int32_t iFind = 0;
- for (; iFind < iCount; iFind++) {
- if (m_PositionedTabs[iFind] > iTabPos) {
- break;
- }
- }
- m_PositionedTabs.InsertAt(iFind, iTabPos);
- if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
- m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
- } else {
- m_bOrphanLine = FALSE;
- }
-}
-void CFX_RTFBreak::SetPositionedTabs(const CFX_FloatArray& tabs) {
- m_PositionedTabs.RemoveAll();
- int32_t iCount = tabs.GetSize();
- m_PositionedTabs.SetSize(iCount);
- int32_t iLineEnd = m_iBoundaryEnd;
- int32_t iTabPos;
- for (int32_t i = 0; i < iCount; i++) {
- iTabPos = FXSYS_round(tabs[i] * 20000.0f) + m_iBoundaryStart;
- if (iTabPos > iLineEnd) {
- iTabPos = iLineEnd;
- }
- m_PositionedTabs[i] = iTabPos;
- }
- if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
- m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
- } else {
- m_bOrphanLine = FALSE;
- }
-}
-void CFX_RTFBreak::ClearPositionedTabs() {
- m_PositionedTabs.RemoveAll();
- m_bOrphanLine = FALSE;
-}
-void CFX_RTFBreak::SetDefaultChar(FX_WCHAR wch) {
- m_wDefChar = wch;
- m_iDefChar = 0;
- if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- if (m_iDefChar < 0) {
- m_iDefChar = 0;
- } else {
- m_iDefChar *= m_iFontSize;
- }
- }
-}
-void CFX_RTFBreak::SetLineBreakChar(FX_WCHAR wch) {
- if (wch != L'\r' && wch != L'\n') {
- return;
- }
- m_wLineBreakChar = wch;
-}
-void CFX_RTFBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) {
- m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
-}
-void CFX_RTFBreak::SetHorizontalScale(int32_t iScale) {
- if (iScale < 0) {
- iScale = 0;
- }
- if (m_iHorizontalScale == iScale) {
- return;
- }
- SetBreakStatus();
- m_iHorizontalScale = iScale;
-}
-void CFX_RTFBreak::SetVerticalScale(int32_t iScale) {
- if (iScale < 0) {
- iScale = 0;
- }
- if (m_iVerticalScale == iScale) {
- return;
- }
- SetBreakStatus();
- m_iVerticalScale = iScale;
-}
-void CFX_RTFBreak::SetCharRotation(int32_t iCharRotation) {
- if (iCharRotation < 0) {
- iCharRotation += (-iCharRotation / 4 + 1) * 4;
- } else if (iCharRotation > 3) {
- iCharRotation -= (iCharRotation / 4) * 4;
- }
- if (m_iCharRotation == iCharRotation) {
- return;
- }
- SetBreakStatus();
- m_iCharRotation = iCharRotation;
- m_iRotation = m_iLineRotation + m_iCharRotation;
- m_iRotation %= 4;
-}
-void CFX_RTFBreak::SetCharSpace(FX_FLOAT fCharSpace) {
- m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
-}
-void CFX_RTFBreak::SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) {
- m_bWordSpace = !bDefault;
- m_iWordSpace = FXSYS_round(fWordSpace * 20000.0f);
-}
-void CFX_RTFBreak::SetReadingOrder(FX_BOOL bRTL) {
- m_bRTL = bRTL;
-}
-void CFX_RTFBreak::SetAlignment(int32_t iAlignment) {
- FXSYS_assert(iAlignment >= FX_RTFLINEALIGNMENT_Left &&
- iAlignment <= FX_RTFLINEALIGNMENT_Distributed);
- m_iAlignment = iAlignment;
-}
-void CFX_RTFBreak::SetUserData(IFX_Unknown* pUserData) {
- if (m_pUserData == pUserData) {
- return;
- }
- SetBreakStatus();
- if (m_pUserData != NULL) {
- m_pUserData->Release();
- }
- m_pUserData = pUserData;
- if (m_pUserData != NULL) {
- m_pUserData->AddRef();
- }
-}
-static const int32_t gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
-int32_t CFX_RTFBreak::GetLineRotation(FX_DWORD dwStyles) const {
- return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1];
-}
-void CFX_RTFBreak::SetBreakStatus() {
- m_dwIdentity++;
- int32_t iCount = m_pCurLine->CountChars();
- if (iCount < 1) {
- return;
- }
- CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1);
- if (tc.m_dwStatus == 0) {
- tc.m_dwStatus = FX_RTFBREAK_PieceBreak;
- }
-}
-CFX_RTFChar* CFX_RTFBreak::GetLastChar(int32_t index) const {
- CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
- int32_t iCount = tca.GetSize();
- if (index < 0 || index >= iCount) {
- return NULL;
- }
- CFX_RTFChar* pTC;
- int32_t iStart = iCount - 1;
- while (iStart > -1) {
- pTC = tca.GetDataPtr(iStart--);
- if (pTC->m_iCharWidth >= 0 ||
- pTC->GetCharType() != FX_CHARTYPE_Combination) {
- if (--index < 0) {
- return pTC;
- }
- }
- }
- return NULL;
-}
-CFX_RTFLine* CFX_RTFBreak::GetRTFLine(FX_BOOL bReady) const {
- if (bReady) {
- if (m_iReady == 1) {
- return (CFX_RTFLine*)&m_RTFLine1;
- } else if (m_iReady == 2) {
- return (CFX_RTFLine*)&m_RTFLine2;
- } else {
- return NULL;
- }
- }
- FXSYS_assert(m_pCurLine != NULL);
- return m_pCurLine;
-}
-CFX_RTFPieceArray* CFX_RTFBreak::GetRTFPieces(FX_BOOL bReady) const {
- CFX_RTFLine* pRTFLine = GetRTFLine(bReady);
- if (pRTFLine == NULL) {
- return NULL;
- }
- return &pRTFLine->m_LinePieces;
-}
-inline FX_DWORD CFX_RTFBreak::GetUnifiedCharType(FX_DWORD dwType) const {
- return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
-}
-int32_t CFX_RTFBreak::GetLastPositionedTab() const {
- int32_t iCount = m_PositionedTabs.GetSize();
- if (iCount < 1) {
- return m_iBoundaryStart;
- }
- return m_PositionedTabs[iCount - 1];
-}
-FX_BOOL CFX_RTFBreak::GetPositionedTab(int32_t& iTabPos) const {
- int32_t iCount = m_PositionedTabs.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- if (m_PositionedTabs[i] > iTabPos) {
- iTabPos = m_PositionedTabs[i];
- return TRUE;
- }
- }
- return FALSE;
-}
-typedef FX_DWORD (CFX_RTFBreak::*FX_RTFBreak_LPFAppendChar)(
- CFX_RTFChar* pCurChar,
- int32_t iRotation);
-static const FX_RTFBreak_LPFAppendChar g_FX_RTFBreak_lpfAppendChar[16] = {
- &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Tab,
- &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Control,
- &CFX_RTFBreak::AppendChar_Combination, &CFX_RTFBreak::AppendChar_Others,
- &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Arabic,
- &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic,
- &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic,
- &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Others,
- &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Others,
-};
-FX_DWORD CFX_RTFBreak::AppendChar(FX_WCHAR wch) {
- FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL && m_pArabicChar != NULL);
- if (m_bCharCode) {
- return AppendChar_CharCode(wch);
- }
- FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
- FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
- CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
- CFX_RTFChar* pCurChar = tca.AddSpace();
- pCurChar->m_dwStatus = 0;
- pCurChar->m_wCharCode = wch;
- pCurChar->m_dwCharProps = dwProps;
- pCurChar->m_dwCharStyles = 0;
- pCurChar->m_dwLayoutStyles = 0;
- pCurChar->m_iFontSize = m_iFontSize;
- pCurChar->m_iFontHeight = m_iFontHeight;
- pCurChar->m_iHorizontalScale = m_iHorizontalScale;
- pCurChar->m_iVertialScale = m_iVerticalScale;
- pCurChar->m_nRotation = m_iCharRotation;
- pCurChar->m_iCharWidth = 0;
- pCurChar->m_dwIdentity = m_dwIdentity;
- if (m_pUserData != NULL) {
- m_pUserData->AddRef();
- }
- pCurChar->m_pUserData = m_pUserData;
- FX_DWORD dwRet1 = FX_RTFBREAK_None;
- if (dwType != FX_CHARTYPE_Combination &&
- GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
- if (!m_bSingleLine && !m_bOrphanLine && m_dwCharType > 0 &&
- m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
- if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
- dwRet1 = EndBreak(FX_RTFBREAK_LineBreak);
- int32_t iCount = m_pCurLine->CountChars();
- if (iCount > 0) {
- pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1);
- }
- }
- }
- }
- int32_t iRotation = m_iRotation;
- if (m_bVertical && (dwProps & 0x8000) != 0) {
- iRotation = (iRotation + 1) % 4;
- }
- FX_DWORD dwRet2 =
- (this->*g_FX_RTFBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(
- pCurChar, iRotation);
- m_dwCharType = dwType;
- return std::max(dwRet1, dwRet2);
-}
-FX_DWORD CFX_RTFBreak::AppendChar_CharCode(FX_WCHAR wch) {
- FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL);
- FXSYS_assert(m_bCharCode);
- m_pCurLine->m_iMBCSChars++;
- CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
- CFX_RTFChar* pCurChar = tca.AddSpace();
- pCurChar->m_dwStatus = 0;
- pCurChar->m_wCharCode = wch;
- pCurChar->m_dwCharProps = 0;
- pCurChar->m_dwCharStyles = 0;
- pCurChar->m_dwLayoutStyles = m_dwLayoutStyles;
- pCurChar->m_iFontSize = m_iFontSize;
- pCurChar->m_iFontHeight = m_iFontHeight;
- pCurChar->m_iHorizontalScale = m_iHorizontalScale;
- pCurChar->m_iVertialScale = m_iVerticalScale;
- pCurChar->m_nRotation = m_iCharRotation;
- pCurChar->m_iCharWidth = 0;
- pCurChar->m_dwIdentity = m_dwIdentity;
- if (m_pUserData != NULL) {
- m_pUserData->AddRef();
- }
- pCurChar->m_pUserData = m_pUserData;
- int32_t iCharWidth = 0;
- if (m_bVertical != FX_IsOdd(m_iRotation)) {
- iCharWidth = 1000;
- } else {
- if (!m_pFont->GetCharWidth(wch, iCharWidth, TRUE)) {
- iCharWidth = m_iDefChar;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorizontalScale / 100;
- iCharWidth += m_iCharSpace;
- pCurChar->m_iCharWidth = iCharWidth;
- m_pCurLine->m_iWidth += iCharWidth;
- m_dwCharType = 0;
- if (!m_bSingleLine &&
- m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
- return EndBreak(FX_RTFBREAK_LineBreak);
- }
- return FX_RTFBREAK_None;
-}
-FX_DWORD CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar* pCurChar,
- int32_t iRotation) {
- int32_t iCharWidth = 0;
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else {
- if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth,
- m_bCharCode)) {
- iCharWidth = 0;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorizontalScale / 100;
- CFX_RTFChar* pLastChar = GetLastChar(0);
- if (pLastChar != NULL && pLastChar->GetCharType() > FX_CHARTYPE_Combination) {
- iCharWidth = -iCharWidth;
- } else {
- m_dwCharType = FX_CHARTYPE_Combination;
- }
- pCurChar->m_iCharWidth = iCharWidth;
- if (iCharWidth > 0) {
- m_pCurLine->m_iWidth += iCharWidth;
- }
- return FX_RTFBREAK_None;
-}
-FX_DWORD CFX_RTFBreak::AppendChar_Tab(CFX_RTFChar* pCurChar,
- int32_t iRotation) {
- if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab) {
- FX_BOOL bBreak = FALSE;
- if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
- bBreak = (m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance);
- }
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- int32_t iCharWidth = iLineWidth;
- if (GetPositionedTab(iCharWidth)) {
- iCharWidth -= iLineWidth;
- } else {
- iCharWidth = m_iTabWidth * (iLineWidth / m_iTabWidth + 1) - iLineWidth;
- }
- pCurChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- if (!m_bSingleLine && !m_bOrphanLine && bBreak) {
- return EndBreak(FX_RTFBREAK_LineBreak);
- }
- }
- return FX_RTFBREAK_None;
-}
-FX_DWORD CFX_RTFBreak::AppendChar_Control(CFX_RTFChar* pCurChar,
- int32_t iRotation) {
- FX_DWORD dwRet2 = FX_RTFBREAK_None;
- if (!m_bSingleLine) {
- switch (pCurChar->m_wCharCode) {
- case L'\v':
- case 0x2028:
- dwRet2 = FX_RTFBREAK_LineBreak;
- break;
- case L'\f':
- dwRet2 = FX_RTFBREAK_PageBreak;
- break;
- case 0x2029:
- dwRet2 = FX_RTFBREAK_ParagraphBreak;
- break;
- default:
- if (pCurChar->m_wCharCode == m_wLineBreakChar) {
- dwRet2 = FX_RTFBREAK_ParagraphBreak;
- }
- break;
- }
- if (dwRet2 != FX_RTFBREAK_None) {
- dwRet2 = EndBreak(dwRet2);
- }
- }
- return dwRet2;
-}
-FX_DWORD CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar* pCurChar,
- int32_t iRotation) {
- CFX_RTFChar* pLastChar = NULL;
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- int32_t iCharWidth = 0;
- FX_WCHAR wForm;
- FX_BOOL bAlef = FALSE;
- if (m_dwCharType >= FX_CHARTYPE_ArabicAlef &&
- m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
- pLastChar = GetLastChar(1);
- if (pLastChar != NULL) {
- iLineWidth -= pLastChar->m_iCharWidth;
- CFX_RTFChar* pPrevChar = GetLastChar(2);
- wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
- bAlef = (wForm == 0xFEFF &&
- pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
- int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
- if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
- iLastRotation++;
- }
- if (m_bVertical != FX_IsOdd(iLastRotation)) {
- iCharWidth = 1000;
- } else {
- if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
- if (!m_pFont->GetCharWidth(pLastChar->m_wCharCode, iCharWidth,
- m_bCharCode)) {
- iCharWidth = m_iDefChar;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorizontalScale / 100;
- pLastChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- iCharWidth = 0;
- }
- }
- wForm =
- m_pArabicChar->GetFormChar(pCurChar, (bAlef ? NULL : pLastChar), NULL);
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else {
- if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
- if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth,
- m_bCharCode)) {
- iCharWidth = m_iDefChar;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorizontalScale / 100;
- pCurChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- m_pCurLine->m_iArabicChars++;
- if (!m_bSingleLine && !m_bOrphanLine &&
- m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
- return EndBreak(FX_RTFBREAK_LineBreak);
- }
- return FX_RTFBREAK_None;
-}
-FX_DWORD CFX_RTFBreak::AppendChar_Others(CFX_RTFChar* pCurChar,
- int32_t iRotation) {
- FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
- FX_WCHAR wForm;
- if (dwType == FX_CHARTYPE_Numeric) {
- if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) {
- wForm = pCurChar->m_wCharCode + 0x0630;
- } else {
- wForm = pCurChar->m_wCharCode;
- }
- } else if (m_bRTL || m_bVertical) {
- wForm = FX_GetMirrorChar(pCurChar->m_wCharCode, pCurChar->m_dwCharProps,
- m_bRTL, m_bVertical);
- } else {
- wForm = pCurChar->m_wCharCode;
- }
- int32_t iCharWidth = 0;
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else {
- if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode)) {
- iCharWidth = m_iDefChar;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorizontalScale / 100;
- iCharWidth += m_iCharSpace;
- if (dwType == FX_CHARTYPE_Space && m_bWordSpace) {
- iCharWidth += m_iWordSpace;
- }
- pCurChar->m_iCharWidth = iCharWidth;
- m_pCurLine->m_iWidth += iCharWidth;
- FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space ||
- (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0);
- if (!m_bSingleLine && !m_bOrphanLine && bBreak &&
- m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
- return EndBreak(FX_RTFBREAK_LineBreak);
- }
- return FX_RTFBREAK_None;
-}
-FX_DWORD CFX_RTFBreak::EndBreak(FX_DWORD dwStatus) {
- FXSYS_assert(dwStatus >= FX_RTFBREAK_PieceBreak &&
- dwStatus <= FX_RTFBREAK_PageBreak);
- m_dwIdentity++;
- CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
- int32_t iCount = pCurPieces->GetSize();
- if (iCount > 0) {
- CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount);
- if (dwStatus > FX_RTFBREAK_PieceBreak) {
- pLastPiece->m_dwStatus = dwStatus;
- } else {
- dwStatus = pLastPiece->m_dwStatus;
- }
- return dwStatus;
- } else {
- CFX_RTFLine* pLastLine = GetRTFLine(TRUE);
- if (pLastLine != NULL) {
- pCurPieces = &pLastLine->m_LinePieces;
- iCount = pCurPieces->GetSize();
- if (iCount-- > 0) {
- CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(iCount);
- if (dwStatus > FX_RTFBREAK_PieceBreak) {
- pLastPiece->m_dwStatus = dwStatus;
- } else {
- dwStatus = pLastPiece->m_dwStatus;
- }
- return dwStatus;
- }
- return FX_RTFBREAK_None;
- }
- iCount = m_pCurLine->CountChars();
- if (iCount < 1) {
- return FX_RTFBREAK_None;
- }
- CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1);
- tc.m_dwStatus = dwStatus;
- if (dwStatus <= FX_RTFBREAK_PieceBreak) {
- return dwStatus;
- }
- }
- m_iReady = (m_pCurLine == &m_RTFLine1) ? 1 : 2;
- CFX_RTFLine* pNextLine =
- (m_pCurLine == &m_RTFLine1) ? &m_RTFLine2 : &m_RTFLine1;
- FX_BOOL bAllChars = (m_iAlignment > FX_RTFLINEALIGNMENT_Right);
- CFX_TPOArray tpos;
- if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
- goto EndBreak_Ret;
- }
- if (!m_bCharCode) {
- EndBreak_BidiLine(tpos, dwStatus);
- }
- if (!m_bPagination && m_iAlignment > FX_RTFLINEALIGNMENT_Left) {
- EndBreak_Alignment(tpos, bAllChars, dwStatus);
- }
-EndBreak_Ret:
- m_pCurLine = pNextLine;
- m_pCurLine->m_iStart = m_iBoundaryStart;
- CFX_RTFChar* pTC = GetLastChar(0);
- m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
- return dwStatus;
-}
-FX_BOOL CFX_RTFBreak::EndBreak_SplitLine(CFX_RTFLine* pNextLine,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus) {
- FX_BOOL bDone = FALSE;
- if (!m_bSingleLine && !m_bOrphanLine &&
- m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
- CFX_RTFChar& tc = m_pCurLine->GetChar(m_pCurLine->CountChars() - 1);
- switch (tc.GetCharType()) {
- case FX_CHARTYPE_Tab:
- if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
- SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
- bDone = TRUE;
- }
- break;
- case FX_CHARTYPE_Control:
- break;
- case FX_CHARTYPE_Space:
- if ((m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0) {
- SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
- bDone = TRUE;
- }
- break;
- default:
- SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
- bDone = TRUE;
- break;
- }
- }
- if (m_bPagination || m_pCurLine->m_iMBCSChars > 0) {
- const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.GetData();
- const CFX_RTFChar* pTC;
- CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
- CFX_RTFPiece tp;
- tp.m_pChars = &m_pCurLine->m_LineChars;
- FX_BOOL bNew = TRUE;
- FX_DWORD dwIdentity = (FX_DWORD)-1;
- int32_t iLast = m_pCurLine->CountChars() - 1, j = 0;
- for (int32_t i = 0; i <= iLast;) {
- pTC = pCurChars + i;
- if (bNew) {
- tp.m_iStartChar = i;
- tp.m_iStartPos += tp.m_iWidth;
- tp.m_iWidth = 0;
- tp.m_dwStatus = pTC->m_dwStatus;
- tp.m_iFontSize = pTC->m_iFontSize;
- tp.m_iFontHeight = pTC->m_iFontHeight;
- tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
- tp.m_iVerticalScale = pTC->m_iVertialScale;
- tp.m_dwLayoutStyles = pTC->m_dwLayoutStyles;
- dwIdentity = pTC->m_dwIdentity;
- tp.m_dwIdentity = dwIdentity;
- tp.m_pUserData = pTC->m_pUserData;
- j = i;
- bNew = FALSE;
- }
- if (i == iLast || pTC->m_dwStatus != FX_RTFBREAK_None ||
- pTC->m_dwIdentity != dwIdentity) {
- tp.m_iChars = i - j;
- if (pTC->m_dwIdentity == dwIdentity) {
- tp.m_dwStatus = pTC->m_dwStatus;
- tp.m_iWidth += pTC->m_iCharWidth;
- tp.m_iChars += 1;
- i++;
- }
- pCurPieces->Add(tp);
- bNew = TRUE;
- } else {
- tp.m_iWidth += pTC->m_iCharWidth;
- i++;
- }
- }
- return TRUE;
- }
- if (bAllChars && !bDone) {
- int32_t iEndPos = m_pCurLine->GetLineEnd();
- GetBreakPos(m_pCurLine->m_LineChars, iEndPos, bAllChars, TRUE);
- }
- return FALSE;
-}
-void CFX_RTFBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus) {
- FX_TPO tpo;
- CFX_RTFPiece tp;
- CFX_RTFChar* pTC;
- int32_t i, j;
- CFX_RTFCharArray& chars = m_pCurLine->m_LineChars;
- int32_t iCount = m_pCurLine->CountChars();
- FX_BOOL bDone = (!m_bPagination && !m_bCharCode &&
- (m_pCurLine->m_iArabicChars > 0 || m_bRTL));
- if (bDone) {
- int32_t iBidiNum = 0;
- for (i = 0; i < iCount; i++) {
- pTC = chars.GetDataPtr(i);
- pTC->m_iBidiPos = i;
- if (pTC->GetCharType() != FX_CHARTYPE_Control) {
- iBidiNum = i;
- }
- if (i == 0) {
- pTC->m_iBidiLevel = 1;
- }
- }
- FX_BidiLine(chars, iBidiNum + 1, m_bRTL ? 1 : 0);
- } else {
- for (i = 0; i < iCount; i++) {
- pTC = chars.GetDataPtr(i);
- pTC->m_iBidiLevel = 0;
- pTC->m_iBidiPos = 0;
- pTC->m_iBidiOrder = 0;
- }
- }
- tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
- tp.m_iStartPos = m_pCurLine->m_iStart;
- tp.m_pChars = &chars;
- CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
- int32_t iBidiLevel = -1, iCharWidth;
- FX_DWORD dwIdentity = (FX_DWORD)-1;
- i = j = 0;
- while (i < iCount) {
- pTC = chars.GetDataPtr(i);
- if (iBidiLevel < 0) {
- iBidiLevel = pTC->m_iBidiLevel;
- iCharWidth = pTC->m_iCharWidth;
- if (iCharWidth < 1) {
- tp.m_iWidth = 0;
- } else {
- tp.m_iWidth = iCharWidth;
- }
- tp.m_iBidiLevel = iBidiLevel;
- tp.m_iBidiPos = pTC->m_iBidiOrder;
- tp.m_iFontSize = pTC->m_iFontSize;
- tp.m_iFontHeight = pTC->m_iFontHeight;
- tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
- tp.m_iVerticalScale = pTC->m_iVertialScale;
- dwIdentity = pTC->m_dwIdentity;
- tp.m_dwIdentity = dwIdentity;
- tp.m_pUserData = pTC->m_pUserData;
- tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
- i++;
- } else if (iBidiLevel != pTC->m_iBidiLevel ||
- pTC->m_dwIdentity != dwIdentity) {
- tp.m_iChars = i - tp.m_iStartChar;
- pCurPieces->Add(tp);
- tp.m_iStartPos += tp.m_iWidth;
- tp.m_iStartChar = i;
- tpo.index = j++;
- tpo.pos = tp.m_iBidiPos;
- tpos.Add(tpo);
- iBidiLevel = -1;
- } else {
- iCharWidth = pTC->m_iCharWidth;
- if (iCharWidth > 0) {
- tp.m_iWidth += iCharWidth;
- }
- i++;
- }
- }
- if (i > tp.m_iStartChar) {
- tp.m_dwStatus = dwStatus;
- tp.m_iChars = i - tp.m_iStartChar;
- pCurPieces->Add(tp);
- tpo.index = j;
- tpo.pos = tp.m_iBidiPos;
- tpos.Add(tpo);
- }
- if (!m_bCharCode) {
- j = tpos.GetSize() - 1;
- FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
- int32_t iStartPos = m_pCurLine->m_iStart;
- for (i = 0; i <= j; i++) {
- tpo = tpos.GetAt(i);
- CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
- ttp.m_iStartPos = iStartPos;
- iStartPos += ttp.m_iWidth;
- }
- }
-}
-void CFX_RTFBreak::EndBreak_Alignment(CFX_TPOArray& tpos,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus) {
- CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
- int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
- int32_t iCount = pCurPieces->GetSize();
- FX_BOOL bFind = FALSE;
- FX_DWORD dwCharType;
- int32_t i, j;
- FX_TPO tpo;
- for (i = iCount - 1; i > -1; i--) {
- tpo = tpos.GetAt(i);
- CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
- if (!bFind) {
- iNetWidth = ttp.GetEndPos();
- }
- FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
- j = bArabic ? 0 : ttp.m_iChars - 1;
- while (j > -1 && j < ttp.m_iChars) {
- const CFX_RTFChar& tc = ttp.GetChar(j);
- if (tc.m_nBreakType == FX_LBT_DIRECT_BRK) {
- iGapChars++;
- }
- if (!bFind || !bAllChars) {
- dwCharType = tc.GetCharType();
- if (dwCharType == FX_CHARTYPE_Space ||
- dwCharType == FX_CHARTYPE_Control) {
- if (!bFind) {
- iCharWidth = tc.m_iCharWidth;
- if (bAllChars && iCharWidth > 0) {
- iNetWidth -= iCharWidth;
- }
- }
- } else {
- bFind = TRUE;
- if (!bAllChars) {
- break;
- }
- }
- }
- j += bArabic ? 1 : -1;
- }
- if (!bAllChars && bFind) {
- break;
- }
- }
- int32_t iOffset = m_iBoundaryEnd - iNetWidth;
- int32_t iLowerAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_LowerMask);
- int32_t iHigherAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_HigherMask);
- if (iGapChars > 0 && (iHigherAlignment == FX_RTFLINEALIGNMENT_Distributed ||
- (iHigherAlignment == FX_RTFLINEALIGNMENT_Justified &&
- dwStatus != FX_RTFBREAK_ParagraphBreak))) {
- int32_t iStart = -1;
- for (i = 0; i < iCount; i++) {
- tpo = tpos.GetAt(i);
- CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
- if (iStart < 0) {
- iStart = ttp.m_iStartPos;
- } else {
- ttp.m_iStartPos = iStart;
- }
- int32_t k;
- for (j = 0; j < ttp.m_iChars; j++) {
- CFX_RTFChar& tc = ttp.GetChar(j);
- if (tc.m_nBreakType != FX_LBT_DIRECT_BRK || tc.m_iCharWidth < 0) {
- continue;
- }
- k = iOffset / iGapChars;
- tc.m_iCharWidth += k;
- ttp.m_iWidth += k;
- iOffset -= k;
- iGapChars--;
- if (iGapChars < 1) {
- break;
- }
- }
- iStart += ttp.m_iWidth;
- }
- } else if (iLowerAlignment > FX_RTFLINEALIGNMENT_Left) {
- if (iLowerAlignment == FX_RTFLINEALIGNMENT_Center) {
- iOffset /= 2;
- }
- if (iOffset > 0) {
- for (i = 0; i < iCount; i++) {
- CFX_RTFPiece& ttp = pCurPieces->GetAt(i);
- ttp.m_iStartPos += iOffset;
- }
- }
- }
-}
-int32_t CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray& tca,
- int32_t& iEndPos,
- FX_BOOL bAllChars,
- FX_BOOL bOnlyBrk) {
- int32_t iLength = tca.GetSize() - 1;
- if (iLength < 1) {
- return iLength;
- }
- int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1,
- iLast = -1, iLastPos = -1;
- if (m_bSingleLine || m_bOrphanLine || iEndPos <= m_iBoundaryEnd) {
- if (!bAllChars || m_bCharCode) {
- return iLength;
- }
- iBreak = iLength;
- iBreakPos = iEndPos;
- }
- CFX_RTFChar* pCharArray = tca.GetData();
- if (m_bCharCode) {
- const CFX_RTFChar* pChar;
- int32_t iCharWidth;
- while (iLength > 0) {
- if (iEndPos <= m_iBoundaryEnd) {
- break;
- }
- pChar = pCharArray + iLength--;
- iCharWidth = pChar->m_iCharWidth;
- if (iCharWidth > 0) {
- iEndPos -= iCharWidth;
- }
- }
- return iLength;
- }
- FX_BOOL bSpaceBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0;
- FX_BOOL bTabBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0;
- FX_BOOL bNumberBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_NumberBreak) != 0;
- FX_BOOL bInfixBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_InfixBreak) != 0;
- FX_LINEBREAKTYPE eType;
- FX_DWORD nCodeProp, nCur, nNext;
- CFX_RTFChar* pCur = pCharArray + iLength--;
- if (bAllChars) {
- pCur->m_nBreakType = FX_LBT_UNKNOWN;
- }
- nCodeProp = pCur->m_dwCharProps;
- nNext = nCodeProp & 0x003F;
- int32_t iCharWidth = pCur->m_iCharWidth;
- if (iCharWidth > 0) {
- iEndPos -= iCharWidth;
- }
- while (iLength >= 0) {
- pCur = pCharArray + iLength;
- nCodeProp = pCur->m_dwCharProps;
- nCur = nCodeProp & 0x003F;
- FX_BOOL bNeedBreak = FALSE;
- if (nCur == FX_CBP_SP) {
- bNeedBreak = !bSpaceBreak;
- if (nNext == FX_CBP_SP) {
- eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (nCur << 5) + nNext);
- }
- } else if (nCur == FX_CBP_TB) {
- bNeedBreak = !bTabBreak;
- if (nNext == FX_CBP_TB) {
- eType = bTabBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (nCur << 5) + nNext);
- }
- } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
- eType = FX_LBT_DIRECT_BRK;
- } else if (bInfixBreak && nCur == FX_CBP_IS && nNext == FX_CBP_IS) {
- eType = FX_LBT_DIRECT_BRK;
- } else {
- if (nNext == FX_CBP_SP) {
- eType = FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (nCur << 5) + nNext);
- }
- }
- if (bAllChars) {
- pCur->m_nBreakType = eType;
- }
- if (!bOnlyBrk) {
- iCharWidth = pCur->m_iCharWidth;
- FX_BOOL bBreak = FALSE;
- if (nCur == FX_CBP_TB && bTabBreak) {
- bBreak = iCharWidth > 0 && iEndPos - iCharWidth <= m_iBoundaryEnd;
- } else {
- bBreak = iEndPos <= m_iBoundaryEnd;
- }
- if (m_bSingleLine || m_bOrphanLine || bBreak || bNeedBreak) {
- if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
- iBreak = iLength;
- iBreakPos = iEndPos;
- if (!bAllChars) {
- return iLength;
- }
- } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
- iIndirect = iLength;
- iIndirectPos = iEndPos;
- }
- if (iLast < 0) {
- iLast = iLength;
- iLastPos = iEndPos;
- }
- }
- if (iCharWidth > 0) {
- iEndPos -= iCharWidth;
- }
- }
- nNext = nCodeProp & 0x003F;
- iLength--;
- }
- if (bOnlyBrk) {
- return 0;
- }
- if (iBreak > -1) {
- iEndPos = iBreakPos;
- return iBreak;
- }
- if (iIndirect > -1) {
- iEndPos = iIndirectPos;
- return iIndirect;
- }
- if (iLast > -1) {
- iEndPos = iLastPos;
- return iLast;
- }
- return 0;
-}
-void CFX_RTFBreak::SplitTextLine(CFX_RTFLine* pCurLine,
- CFX_RTFLine* pNextLine,
- FX_BOOL bAllChars) {
- FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
- int32_t iCount = pCurLine->CountChars();
- if (iCount < 2) {
- return;
- }
- int32_t iEndPos = pCurLine->GetLineEnd();
- CFX_RTFCharArray& curChars = pCurLine->m_LineChars;
- int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
- if (iCharPos < 0) {
- iCharPos = 0;
- }
- iCharPos++;
- if (iCharPos >= iCount) {
- pNextLine->RemoveAll(TRUE);
- CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
- pTC->m_nBreakType = FX_LBT_UNKNOWN;
- return;
- }
- CFX_RTFCharArray& nextChars = pNextLine->m_LineChars;
- int cur_size = curChars.GetSize();
- nextChars.SetSize(cur_size - iCharPos);
- FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
- (cur_size - iCharPos) * sizeof(CFX_RTFChar));
- iCount -= iCharPos;
- cur_size = curChars.GetSize();
- curChars.RemoveAt(cur_size - iCount, iCount);
- pNextLine->m_iStart = pCurLine->m_iStart;
- pNextLine->m_iWidth = pCurLine->GetLineEnd() - iEndPos;
- pCurLine->m_iWidth = iEndPos;
- CFX_RTFChar* tc = curChars.GetDataPtr(iCharPos - 1);
- tc->m_nBreakType = FX_LBT_UNKNOWN;
- iCount = nextChars.GetSize();
- CFX_RTFChar* pNextChars = nextChars.GetData();
- for (int32_t i = 0; i < iCount; i++) {
- CFX_RTFChar* tc = pNextChars + i;
- if (tc->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
- pCurLine->m_iArabicChars--;
- pNextLine->m_iArabicChars++;
- }
- if (tc->m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) {
- pCurLine->m_iMBCSChars--;
- pNextLine->m_iMBCSChars++;
- }
- tc->m_dwStatus = 0;
- }
-}
-int32_t CFX_RTFBreak::CountBreakPieces() const {
- CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(TRUE);
- if (pRTFPieces == NULL) {
- return 0;
- }
- return pRTFPieces->GetSize();
-}
-const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(int32_t index) const {
- CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(TRUE);
- if (pRTFPieces == NULL) {
- return NULL;
- }
- if (index < 0 || index >= pRTFPieces->GetSize()) {
- return NULL;
- }
- return pRTFPieces->GetPtrAt(index);
-}
-void CFX_RTFBreak::GetLineRect(CFX_RectF& rect) const {
- rect.top = 0;
- CFX_RTFLine* pRTFLine = GetRTFLine(TRUE);
- if (pRTFLine == NULL) {
- rect.left = ((FX_FLOAT)m_iBoundaryStart) / 20000.0f;
- rect.width = rect.height = 0;
- return;
- }
- rect.left = ((FX_FLOAT)pRTFLine->m_iStart) / 20000.0f;
- rect.width = ((FX_FLOAT)pRTFLine->m_iWidth) / 20000.0f;
- CFX_RTFPieceArray& rtfPieces = pRTFLine->m_LinePieces;
- int32_t iCount = rtfPieces.GetSize();
- if (iCount < 1) {
- rect.width = 0;
- return;
- }
- CFX_RTFPiece* pBreakPiece;
- int32_t iLineHeight = 0, iMax;
- for (int32_t i = 0; i < iCount; i++) {
- pBreakPiece = rtfPieces.GetPtrAt(i);
- int32_t iFontHeight = FXSYS_round(pBreakPiece->m_iFontHeight *
- pBreakPiece->m_iVerticalScale / 100.0f);
- iMax = std::max(pBreakPiece->m_iFontSize, iFontHeight);
- if (i == 0) {
- iLineHeight = iMax;
- } else if (iLineHeight < iMax) {
- iLineHeight = iMax;
- }
- }
- rect.height = ((FX_FLOAT)iLineHeight) / 20.0f;
-}
-void CFX_RTFBreak::ClearBreakPieces() {
- CFX_RTFLine* pRTFLine = GetRTFLine(TRUE);
- if (pRTFLine != NULL) {
- pRTFLine->RemoveAll(TRUE);
- }
- m_iReady = 0;
-}
-void CFX_RTFBreak::Reset() {
- m_dwCharType = 0;
- m_RTFLine1.RemoveAll(TRUE);
- m_RTFLine2.RemoveAll(TRUE);
-}
-int32_t CFX_RTFBreak::GetDisplayPos(FX_LPCRTFTEXTOBJ pText,
- FXTEXT_CHARPOS* pCharPos,
- FX_BOOL bCharCode,
- CFX_WideString* pWSForms,
- FX_AdjustCharDisplayPos pAdjustPos) const {
- if (pText == NULL || pText->iLength < 1) {
- return 0;
- }
- FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL &&
- pText->pFont != NULL && pText->pRect != NULL);
- const FX_WCHAR* pStr = pText->pStr;
- int32_t* pWidths = pText->pWidths;
- int32_t iLength = pText->iLength - 1;
- IFX_Font* pFont = pText->pFont;
- FX_DWORD dwStyles = pText->dwLayoutStyles;
- CFX_RectF rtText(*pText->pRect);
- FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
- FX_FLOAT fFontSize = pText->fFontSize;
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- int32_t iAscent = pFont->GetAscent();
- int32_t iDescent = pFont->GetDescent();
- int32_t iMaxHeight = iAscent - iDescent;
- FX_FLOAT fFontHeight = fFontSize;
- FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
- FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
- FX_BOOL bVerticalDoc = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
- FX_BOOL bVerticalChar = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
- FX_BOOL bArabicNumber = (dwStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) != 0;
- FX_BOOL bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
- int32_t iRotation = GetLineRotation(dwStyles) + pText->iCharRotation;
- int32_t iCharRotation;
- FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm;
- int32_t iWidth, iCharWidth, iCharHeight;
- FX_FLOAT fX, fY, fCharWidth, fCharHeight;
- int32_t iHorScale = pText->iHorizontalScale;
- int32_t iVerScale = pText->iVerticalScale;
- FX_BOOL bEmptyChar;
- FX_DWORD dwProps, dwCharType;
- fX = rtText.left;
- fY = rtText.top;
- if (bVerticalDoc) {
- fX += (rtText.width - fFontSize) / 2.0f;
- if (bRTLPiece) {
- fY = rtText.bottom();
- }
- } else {
- if (bRTLPiece) {
- fX = rtText.right();
- }
- fY += fAscent;
- }
- int32_t iCount = 0;
- for (int32_t i = 0; i <= iLength; i++) {
- wch = *pStr++;
- iWidth = *pWidths++;
- if (!bMBCSCode) {
- dwProps = FX_GetUnicodeProperties(wch);
- dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
- if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
- wPrev = 0xFEFF;
- continue;
- }
- } else {
- dwProps = 0;
- dwCharType = 0;
- }
- if (iWidth != 0) {
- iCharWidth = iWidth;
- if (iCharWidth < 0) {
- iCharWidth = -iCharWidth;
- }
- if (!bMBCSCode) {
- bEmptyChar = (dwCharType >= FX_CHARTYPE_Tab &&
- dwCharType <= FX_CHARTYPE_Control);
- } else {
- bEmptyChar = FALSE;
- }
- if (!bEmptyChar) {
- iCount++;
- }
- if (pCharPos != NULL) {
- iCharWidth /= iFontSize;
- wForm = wch;
- if (!bMBCSCode) {
- if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
- if (i < iLength) {
- wNext = *pStr;
- if (*pWidths < 0) {
- if (i + 1 < iLength) {
- wNext = pStr[1];
- }
- }
- } else {
- wNext = 0xFEFF;
- }
- wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
- } else if (bRTLPiece || bVerticalChar) {
- wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
- } else if (dwCharType == FX_CHARTYPE_Numeric && bArabicNumber) {
- wForm = wch + 0x0630;
- }
- dwProps = FX_GetUnicodeProperties(wForm);
- }
- iCharRotation = iRotation;
- if (!bMBCSCode && bVerticalChar && (dwProps & 0x8000) != 0) {
- iCharRotation++;
- iCharRotation %= 4;
- }
- if (!bEmptyChar) {
- if (bCharCode) {
- pCharPos->m_GlyphIndex = wch;
- } else {
- pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm, bMBCSCode);
- if (pCharPos->m_GlyphIndex == 0xFFFF) {
- pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch, bMBCSCode);
- }
- }
- pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
- pCharPos->m_FontCharWidth = iCharWidth;
- if (pWSForms) {
- *pWSForms += wForm;
- }
- }
- if (bVerticalDoc) {
- iCharHeight = iCharWidth;
- iCharWidth = 1000;
- } else {
- iCharHeight = 1000;
- }
- fCharWidth = fFontSize * iCharWidth / 1000.0f;
- fCharHeight = fFontSize * iCharHeight / 1000.0f;
- if (!bMBCSCode && bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
- if (bVerticalDoc) {
- fY -= fCharHeight;
- } else {
- fX -= fCharWidth;
- }
- }
- if (!bEmptyChar) {
- CFX_PointF ptOffset;
- ptOffset.Reset();
- FX_BOOL bAdjusted = FALSE;
- if (pAdjustPos) {
- bAdjusted = pAdjustPos(wForm, bMBCSCode, pFont, fFontSize,
- bVerticalChar, ptOffset);
- }
- if (!pAdjustPos && bVerticalChar && (dwProps & 0x00010000) != 0) {
- CFX_Rect rtBBox;
- rtBBox.Reset();
- if (pFont->GetCharBBox(wForm, rtBBox, bMBCSCode)) {
- ptOffset.x = fFontSize * (850 - rtBBox.right()) / 1000.0f;
- ptOffset.y = fFontSize * (1000 - rtBBox.height) / 2000.0f;
- }
- }
- pCharPos->m_OriginX = fX + ptOffset.x;
- pCharPos->m_OriginY = fY - ptOffset.y;
- }
- if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
- if (bVerticalDoc) {
- fY += fCharHeight;
- } else {
- fX += fCharWidth;
- }
- }
- if (!bEmptyChar) {
- pCharPos->m_bGlyphAdjust = TRUE;
- if (bVerticalDoc) {
- if (iCharRotation == 0) {
- pCharPos->m_AdjustMatrix[0] = -1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = 1;
- pCharPos->m_OriginY += fAscent * iVerScale / 100.0f;
- } else if (iCharRotation == 1) {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = -1;
- pCharPos->m_AdjustMatrix[2] = -1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX -=
- fDescent + fAscent * iVerScale / 100.0f - fAscent;
- } else if (iCharRotation == 2) {
- pCharPos->m_AdjustMatrix[0] = 1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = -1;
- pCharPos->m_OriginX += fCharWidth;
- pCharPos->m_OriginY += fAscent;
- } else {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = 1;
- pCharPos->m_AdjustMatrix[2] = 1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX += fAscent;
- pCharPos->m_OriginY += fCharWidth;
- }
- } else {
- if (iCharRotation == 0) {
- pCharPos->m_AdjustMatrix[0] = -1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = 1;
- pCharPos->m_OriginY += fAscent * iVerScale / 100.0f - fAscent;
- } else if (iCharRotation == 1) {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = -1;
- pCharPos->m_AdjustMatrix[2] = -1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX -= fDescent;
- pCharPos->m_OriginY -= fAscent + fDescent;
- } else if (iCharRotation == 2) {
- pCharPos->m_AdjustMatrix[0] = 1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = -1;
- pCharPos->m_OriginX += fCharWidth;
- pCharPos->m_OriginY -= fAscent;
- } else {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = 1;
- pCharPos->m_AdjustMatrix[2] = 1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX += fAscent * iVerScale / 100.0f;
- }
- }
- 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 (iWidth > 0) {
- wPrev = wch;
- }
- }
- return iCount;
-}
-int32_t CFX_RTFBreak::GetCharRects(FX_LPCRTFTEXTOBJ pText,
- CFX_RectFArray& rtArray,
- FX_BOOL bCharBBox) const {
- if (pText == NULL || pText->iLength < 1) {
- return 0;
- }
- FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL &&
- pText->pFont != NULL && pText->pRect != NULL);
- const FX_WCHAR* pStr = pText->pStr;
- int32_t* pWidths = pText->pWidths;
- int32_t iLength = pText->iLength;
- CFX_RectF rect(*pText->pRect);
- FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
- FX_FLOAT fFontSize = pText->fFontSize;
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- FX_FLOAT fScale = fFontSize / 1000.0f;
- IFX_Font* pFont = pText->pFont;
- if (pFont == NULL) {
- bCharBBox = FALSE;
- }
- CFX_Rect bbox;
- bbox.Set(0, 0, 0, 0);
- if (bCharBBox) {
- bCharBBox = pFont->GetBBox(bbox);
- }
- FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
- FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
- rtArray.RemoveAll();
- rtArray.SetSize(iLength);
- FX_DWORD dwStyles = pText->dwLayoutStyles;
- FX_BOOL bVertical = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
- FX_BOOL bSingleLine = (dwStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
- FX_BOOL bCombText = (dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
- FX_WCHAR wch, wLineBreakChar = pText->wLineBreakChar;
- int32_t iCharSize;
- FX_FLOAT fCharSize, fStart;
- if (bVertical) {
- fStart = bRTLPiece ? rect.bottom() : rect.top;
- } else {
- fStart = bRTLPiece ? rect.right() : rect.left;
- }
- for (int32_t i = 0; i < iLength; i++) {
- wch = *pStr++;
- iCharSize = *pWidths++;
- fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
- FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
- if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 ||
- (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
- bRet = FALSE;
- }
- if (bRet) {
- iCharSize = iFontSize * 500;
- fCharSize = fFontSize / 2.0f;
- }
- if (bVertical) {
- rect.top = fStart;
- if (bRTLPiece) {
- rect.top -= fCharSize;
- fStart -= fCharSize;
- } else {
- fStart += fCharSize;
- }
- rect.height = fCharSize;
- } else {
- rect.left = fStart;
- if (bRTLPiece) {
- rect.left -= fCharSize;
- fStart -= fCharSize;
- } else {
- fStart += fCharSize;
- }
- rect.width = fCharSize;
- }
- if (bCharBBox && !bRet) {
- int32_t iCharWidth = 1000;
- pFont->GetCharWidth(wch, iCharWidth);
- FX_FLOAT fRTLeft = 0, fCharWidth = 0;
- if (iCharWidth > 0) {
- fCharWidth = iCharWidth * fScale;
- fRTLeft = fLeft;
- if (bCombText) {
- fRTLeft = (rect.width - fCharWidth) / 2.0f;
- }
- }
- CFX_RectF rtBBoxF;
- if (bVertical) {
- rtBBoxF.top = rect.left + fRTLeft;
- rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
- rtBBoxF.height = fCharWidth;
- rtBBoxF.width = fHeight;
- rtBBoxF.left = std::max(rtBBoxF.left, 0.0f);
- } else {
- rtBBoxF.left = rect.left + fRTLeft;
- rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
- rtBBoxF.width = fCharWidth;
- rtBBoxF.height = fHeight;
- rtBBoxF.top = std::max(rtBBoxF.top, 0.0f);
- }
- rtArray.SetAt(i, rtBBoxF);
- continue;
- }
- rtArray.SetAt(i, rect);
- }
- return iLength;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/include/fx_lbk.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "xfa/src/fgas/src/layout/fx_unicode.h"
+#include "xfa/src/fgas/src/layout/fx_rtfbreak.h"
+
+IFX_RTFBreak* IFX_RTFBreak::Create(FX_DWORD dwPolicies) {
+ return new CFX_RTFBreak(dwPolicies);
+}
+CFX_RTFBreak::CFX_RTFBreak(FX_DWORD dwPolicies)
+ : m_dwPolicies(dwPolicies),
+ m_pArabicChar(NULL),
+ m_iBoundaryStart(0),
+ m_iBoundaryEnd(2000000),
+ m_dwLayoutStyles(0),
+ m_bPagination(FALSE),
+ m_bVertical(FALSE),
+ m_bSingleLine(FALSE),
+ m_bCharCode(FALSE),
+ m_pFont(NULL),
+ m_iFontHeight(240),
+ m_iFontSize(240),
+ m_iTabWidth(720000),
+ m_PositionedTabs(),
+ m_bOrphanLine(FALSE),
+ m_wDefChar(0xFEFF),
+ m_iDefChar(0),
+ m_wLineBreakChar(L'\n'),
+ m_iHorizontalScale(100),
+ m_iVerticalScale(100),
+ m_iLineRotation(0),
+ m_iCharRotation(0),
+ m_iRotation(0),
+ m_iCharSpace(0),
+ m_bWordSpace(FALSE),
+ m_iWordSpace(0),
+ m_bRTL(FALSE),
+ m_iAlignment(FX_RTFLINEALIGNMENT_Left),
+ m_pUserData(NULL),
+ m_dwCharType(0),
+ m_dwIdentity(0),
+ m_RTFLine1(),
+ m_RTFLine2(),
+ m_pCurLine(NULL),
+ m_iReady(0),
+ m_iTolerance(0) {
+ m_pArabicChar = IFX_ArabicChar::Create();
+ m_pCurLine = &m_RTFLine1;
+}
+CFX_RTFBreak::~CFX_RTFBreak() {
+ Reset();
+ m_PositionedTabs.RemoveAll();
+ m_pArabicChar->Release();
+ if (m_pUserData != NULL) {
+ m_pUserData->Release();
+ }
+}
+void CFX_RTFBreak::SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) {
+ if (fLineStart > fLineEnd)
+ return;
+ m_iBoundaryStart = FXSYS_round(fLineStart * 20000.0f);
+ m_iBoundaryEnd = FXSYS_round(fLineEnd * 20000.0f);
+ m_pCurLine->m_iStart = std::min(m_pCurLine->m_iStart, m_iBoundaryEnd);
+ m_pCurLine->m_iStart = std::max(m_pCurLine->m_iStart, m_iBoundaryStart);
+}
+void CFX_RTFBreak::SetLineStartPos(FX_FLOAT fLinePos) {
+ int32_t iLinePos = FXSYS_round(fLinePos * 20000.0f);
+ iLinePos = std::min(iLinePos, m_iBoundaryEnd);
+ iLinePos = std::max(iLinePos, m_iBoundaryStart);
+ m_pCurLine->m_iStart = iLinePos;
+}
+void CFX_RTFBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles) {
+ if (m_dwLayoutStyles == dwLayoutStyles) {
+ return;
+ }
+ SetBreakStatus();
+ m_dwLayoutStyles = dwLayoutStyles;
+ m_bPagination = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination) != 0;
+ m_bVertical = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
+ m_bSingleLine = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
+ m_bCharCode = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
+ m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_RTFBreak::SetFont(IFX_Font* pFont) {
+ if (pFont == NULL) {
+ return;
+ }
+ if (m_pFont == pFont) {
+ return;
+ }
+ SetBreakStatus();
+ m_pFont = pFont;
+ m_iDefChar = 0;
+ if (m_pFont != NULL) {
+ m_iFontHeight = m_iFontSize;
+ if (m_wDefChar != 0xFEFF) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize) {
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ if (m_iFontSize == iFontSize) {
+ return;
+ }
+ SetBreakStatus();
+ m_iFontSize = iFontSize;
+ m_iDefChar = 0;
+ if (m_pFont != NULL) {
+ m_iFontHeight = m_iFontSize;
+ if (m_wDefChar != 0xFEFF) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetTabWidth(FX_FLOAT fTabWidth) {
+ m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
+}
+void CFX_RTFBreak::AddPositionedTab(FX_FLOAT fTabPos) {
+ int32_t iLineEnd = m_iBoundaryEnd;
+ int32_t iTabPos = FXSYS_round(fTabPos * 20000.0f) + m_iBoundaryStart;
+ if (iTabPos > iLineEnd) {
+ iTabPos = iLineEnd;
+ }
+ if (m_PositionedTabs.Find(iTabPos, 0) > -1) {
+ return;
+ }
+ int32_t iCount = m_PositionedTabs.GetSize();
+ int32_t iFind = 0;
+ for (; iFind < iCount; iFind++) {
+ if (m_PositionedTabs[iFind] > iTabPos) {
+ break;
+ }
+ }
+ m_PositionedTabs.InsertAt(iFind, iTabPos);
+ if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
+ m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
+ } else {
+ m_bOrphanLine = FALSE;
+ }
+}
+void CFX_RTFBreak::SetPositionedTabs(const CFX_FloatArray& tabs) {
+ m_PositionedTabs.RemoveAll();
+ int32_t iCount = tabs.GetSize();
+ m_PositionedTabs.SetSize(iCount);
+ int32_t iLineEnd = m_iBoundaryEnd;
+ int32_t iTabPos;
+ for (int32_t i = 0; i < iCount; i++) {
+ iTabPos = FXSYS_round(tabs[i] * 20000.0f) + m_iBoundaryStart;
+ if (iTabPos > iLineEnd) {
+ iTabPos = iLineEnd;
+ }
+ m_PositionedTabs[i] = iTabPos;
+ }
+ if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
+ m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
+ } else {
+ m_bOrphanLine = FALSE;
+ }
+}
+void CFX_RTFBreak::ClearPositionedTabs() {
+ m_PositionedTabs.RemoveAll();
+ m_bOrphanLine = FALSE;
+}
+void CFX_RTFBreak::SetDefaultChar(FX_WCHAR wch) {
+ m_wDefChar = wch;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ if (m_iDefChar < 0) {
+ m_iDefChar = 0;
+ } else {
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetLineBreakChar(FX_WCHAR wch) {
+ if (wch != L'\r' && wch != L'\n') {
+ return;
+ }
+ m_wLineBreakChar = wch;
+}
+void CFX_RTFBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) {
+ m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
+}
+void CFX_RTFBreak::SetHorizontalScale(int32_t iScale) {
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (m_iHorizontalScale == iScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iHorizontalScale = iScale;
+}
+void CFX_RTFBreak::SetVerticalScale(int32_t iScale) {
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (m_iVerticalScale == iScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iVerticalScale = iScale;
+}
+void CFX_RTFBreak::SetCharRotation(int32_t iCharRotation) {
+ if (iCharRotation < 0) {
+ iCharRotation += (-iCharRotation / 4 + 1) * 4;
+ } else if (iCharRotation > 3) {
+ iCharRotation -= (iCharRotation / 4) * 4;
+ }
+ if (m_iCharRotation == iCharRotation) {
+ return;
+ }
+ SetBreakStatus();
+ m_iCharRotation = iCharRotation;
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_RTFBreak::SetCharSpace(FX_FLOAT fCharSpace) {
+ m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
+}
+void CFX_RTFBreak::SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) {
+ m_bWordSpace = !bDefault;
+ m_iWordSpace = FXSYS_round(fWordSpace * 20000.0f);
+}
+void CFX_RTFBreak::SetReadingOrder(FX_BOOL bRTL) {
+ m_bRTL = bRTL;
+}
+void CFX_RTFBreak::SetAlignment(int32_t iAlignment) {
+ FXSYS_assert(iAlignment >= FX_RTFLINEALIGNMENT_Left &&
+ iAlignment <= FX_RTFLINEALIGNMENT_Distributed);
+ m_iAlignment = iAlignment;
+}
+void CFX_RTFBreak::SetUserData(IFX_Unknown* pUserData) {
+ if (m_pUserData == pUserData) {
+ return;
+ }
+ SetBreakStatus();
+ if (m_pUserData != NULL) {
+ m_pUserData->Release();
+ }
+ m_pUserData = pUserData;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+}
+static const int32_t gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
+int32_t CFX_RTFBreak::GetLineRotation(FX_DWORD dwStyles) const {
+ return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1];
+}
+void CFX_RTFBreak::SetBreakStatus() {
+ m_dwIdentity++;
+ int32_t iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return;
+ }
+ CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1);
+ if (tc.m_dwStatus == 0) {
+ tc.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ }
+}
+CFX_RTFChar* CFX_RTFBreak::GetLastChar(int32_t index) const {
+ CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
+ int32_t iCount = tca.GetSize();
+ if (index < 0 || index >= iCount) {
+ return NULL;
+ }
+ CFX_RTFChar* pTC;
+ int32_t iStart = iCount - 1;
+ while (iStart > -1) {
+ pTC = tca.GetDataPtr(iStart--);
+ if (pTC->m_iCharWidth >= 0 ||
+ pTC->GetCharType() != FX_CHARTYPE_Combination) {
+ if (--index < 0) {
+ return pTC;
+ }
+ }
+ }
+ return NULL;
+}
+CFX_RTFLine* CFX_RTFBreak::GetRTFLine(FX_BOOL bReady) const {
+ if (bReady) {
+ if (m_iReady == 1) {
+ return (CFX_RTFLine*)&m_RTFLine1;
+ } else if (m_iReady == 2) {
+ return (CFX_RTFLine*)&m_RTFLine2;
+ } else {
+ return NULL;
+ }
+ }
+ FXSYS_assert(m_pCurLine != NULL);
+ return m_pCurLine;
+}
+CFX_RTFPieceArray* CFX_RTFBreak::GetRTFPieces(FX_BOOL bReady) const {
+ CFX_RTFLine* pRTFLine = GetRTFLine(bReady);
+ if (pRTFLine == NULL) {
+ return NULL;
+ }
+ return &pRTFLine->m_LinePieces;
+}
+inline FX_DWORD CFX_RTFBreak::GetUnifiedCharType(FX_DWORD dwType) const {
+ return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
+}
+int32_t CFX_RTFBreak::GetLastPositionedTab() const {
+ int32_t iCount = m_PositionedTabs.GetSize();
+ if (iCount < 1) {
+ return m_iBoundaryStart;
+ }
+ return m_PositionedTabs[iCount - 1];
+}
+FX_BOOL CFX_RTFBreak::GetPositionedTab(int32_t& iTabPos) const {
+ int32_t iCount = m_PositionedTabs.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ if (m_PositionedTabs[i] > iTabPos) {
+ iTabPos = m_PositionedTabs[i];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+typedef FX_DWORD (CFX_RTFBreak::*FX_RTFBreak_LPFAppendChar)(
+ CFX_RTFChar* pCurChar,
+ int32_t iRotation);
+static const FX_RTFBreak_LPFAppendChar g_FX_RTFBreak_lpfAppendChar[16] = {
+ &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Tab,
+ &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Control,
+ &CFX_RTFBreak::AppendChar_Combination, &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Others,
+};
+FX_DWORD CFX_RTFBreak::AppendChar(FX_WCHAR wch) {
+ FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL && m_pArabicChar != NULL);
+ if (m_bCharCode) {
+ return AppendChar_CharCode(wch);
+ }
+ FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
+ CFX_RTFChar* pCurChar = tca.AddSpace();
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_wCharCode = wch;
+ pCurChar->m_dwCharProps = dwProps;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_dwLayoutStyles = 0;
+ pCurChar->m_iFontSize = m_iFontSize;
+ pCurChar->m_iFontHeight = m_iFontHeight;
+ pCurChar->m_iHorizontalScale = m_iHorizontalScale;
+ pCurChar->m_iVertialScale = m_iVerticalScale;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_dwIdentity = m_dwIdentity;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+ pCurChar->m_pUserData = m_pUserData;
+ FX_DWORD dwRet1 = FX_RTFBREAK_None;
+ if (dwType != FX_CHARTYPE_Combination &&
+ GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
+ if (!m_bSingleLine && !m_bOrphanLine && m_dwCharType > 0 &&
+ m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
+ if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
+ dwRet1 = EndBreak(FX_RTFBREAK_LineBreak);
+ int32_t iCount = m_pCurLine->CountChars();
+ if (iCount > 0) {
+ pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1);
+ }
+ }
+ }
+ }
+ int32_t iRotation = m_iRotation;
+ if (m_bVertical && (dwProps & 0x8000) != 0) {
+ iRotation = (iRotation + 1) % 4;
+ }
+ FX_DWORD dwRet2 =
+ (this->*g_FX_RTFBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(
+ pCurChar, iRotation);
+ m_dwCharType = dwType;
+ return std::max(dwRet1, dwRet2);
+}
+FX_DWORD CFX_RTFBreak::AppendChar_CharCode(FX_WCHAR wch) {
+ FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL);
+ FXSYS_assert(m_bCharCode);
+ m_pCurLine->m_iMBCSChars++;
+ CFX_RTFCharArray& tca = m_pCurLine->m_LineChars;
+ CFX_RTFChar* pCurChar = tca.AddSpace();
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_wCharCode = wch;
+ pCurChar->m_dwCharProps = 0;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_dwLayoutStyles = m_dwLayoutStyles;
+ pCurChar->m_iFontSize = m_iFontSize;
+ pCurChar->m_iFontHeight = m_iFontHeight;
+ pCurChar->m_iHorizontalScale = m_iHorizontalScale;
+ pCurChar->m_iVertialScale = m_iVerticalScale;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_dwIdentity = m_dwIdentity;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+ pCurChar->m_pUserData = m_pUserData;
+ int32_t iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(m_iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wch, iCharWidth, TRUE)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ iCharWidth += m_iCharSpace;
+ pCurChar->m_iCharWidth = iCharWidth;
+ m_pCurLine->m_iWidth += iCharWidth;
+ m_dwCharType = 0;
+ if (!m_bSingleLine &&
+ m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar* pCurChar,
+ int32_t iRotation) {
+ int32_t iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth,
+ m_bCharCode)) {
+ iCharWidth = 0;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ CFX_RTFChar* pLastChar = GetLastChar(0);
+ if (pLastChar != NULL && pLastChar->GetCharType() > FX_CHARTYPE_Combination) {
+ iCharWidth = -iCharWidth;
+ } else {
+ m_dwCharType = FX_CHARTYPE_Combination;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ if (iCharWidth > 0) {
+ m_pCurLine->m_iWidth += iCharWidth;
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Tab(CFX_RTFChar* pCurChar,
+ int32_t iRotation) {
+ if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab) {
+ FX_BOOL bBreak = FALSE;
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
+ bBreak = (m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance);
+ }
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ int32_t iCharWidth = iLineWidth;
+ if (GetPositionedTab(iCharWidth)) {
+ iCharWidth -= iLineWidth;
+ } else {
+ iCharWidth = m_iTabWidth * (iLineWidth / m_iTabWidth + 1) - iLineWidth;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ if (!m_bSingleLine && !m_bOrphanLine && bBreak) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Control(CFX_RTFChar* pCurChar,
+ int32_t iRotation) {
+ FX_DWORD dwRet2 = FX_RTFBREAK_None;
+ if (!m_bSingleLine) {
+ switch (pCurChar->m_wCharCode) {
+ case L'\v':
+ case 0x2028:
+ dwRet2 = FX_RTFBREAK_LineBreak;
+ break;
+ case L'\f':
+ dwRet2 = FX_RTFBREAK_PageBreak;
+ break;
+ case 0x2029:
+ dwRet2 = FX_RTFBREAK_ParagraphBreak;
+ break;
+ default:
+ if (pCurChar->m_wCharCode == m_wLineBreakChar) {
+ dwRet2 = FX_RTFBREAK_ParagraphBreak;
+ }
+ break;
+ }
+ if (dwRet2 != FX_RTFBREAK_None) {
+ dwRet2 = EndBreak(dwRet2);
+ }
+ }
+ return dwRet2;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar* pCurChar,
+ int32_t iRotation) {
+ CFX_RTFChar* pLastChar = NULL;
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ int32_t iCharWidth = 0;
+ FX_WCHAR wForm;
+ FX_BOOL bAlef = FALSE;
+ if (m_dwCharType >= FX_CHARTYPE_ArabicAlef &&
+ m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
+ pLastChar = GetLastChar(1);
+ if (pLastChar != NULL) {
+ iLineWidth -= pLastChar->m_iCharWidth;
+ CFX_RTFChar* pPrevChar = GetLastChar(2);
+ wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
+ bAlef = (wForm == 0xFEFF &&
+ pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
+ int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
+ if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
+ iLastRotation++;
+ }
+ if (m_bVertical != FX_IsOdd(iLastRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
+ if (!m_pFont->GetCharWidth(pLastChar->m_wCharCode, iCharWidth,
+ m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ pLastChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ iCharWidth = 0;
+ }
+ }
+ wForm =
+ m_pArabicChar->GetFormChar(pCurChar, (bAlef ? NULL : pLastChar), NULL);
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
+ if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth,
+ m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ m_pCurLine->m_iArabicChars++;
+ if (!m_bSingleLine && !m_bOrphanLine &&
+ m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Others(CFX_RTFChar* pCurChar,
+ int32_t iRotation) {
+ FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
+ FX_WCHAR wForm;
+ if (dwType == FX_CHARTYPE_Numeric) {
+ if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) {
+ wForm = pCurChar->m_wCharCode + 0x0630;
+ } else {
+ wForm = pCurChar->m_wCharCode;
+ }
+ } else if (m_bRTL || m_bVertical) {
+ wForm = FX_GetMirrorChar(pCurChar->m_wCharCode, pCurChar->m_dwCharProps,
+ m_bRTL, m_bVertical);
+ } else {
+ wForm = pCurChar->m_wCharCode;
+ }
+ int32_t iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ iCharWidth += m_iCharSpace;
+ if (dwType == FX_CHARTYPE_Space && m_bWordSpace) {
+ iCharWidth += m_iWordSpace;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ m_pCurLine->m_iWidth += iCharWidth;
+ FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space ||
+ (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0);
+ if (!m_bSingleLine && !m_bOrphanLine && bBreak &&
+ m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::EndBreak(FX_DWORD dwStatus) {
+ FXSYS_assert(dwStatus >= FX_RTFBREAK_PieceBreak &&
+ dwStatus <= FX_RTFBREAK_PageBreak);
+ m_dwIdentity++;
+ CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
+ int32_t iCount = pCurPieces->GetSize();
+ if (iCount > 0) {
+ CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount);
+ if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ } else {
+ CFX_RTFLine* pLastLine = GetRTFLine(TRUE);
+ if (pLastLine != NULL) {
+ pCurPieces = &pLastLine->m_LinePieces;
+ iCount = pCurPieces->GetSize();
+ if (iCount-- > 0) {
+ CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(iCount);
+ if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ }
+ return FX_RTFBREAK_None;
+ }
+ iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return FX_RTFBREAK_None;
+ }
+ CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1);
+ tc.m_dwStatus = dwStatus;
+ if (dwStatus <= FX_RTFBREAK_PieceBreak) {
+ return dwStatus;
+ }
+ }
+ m_iReady = (m_pCurLine == &m_RTFLine1) ? 1 : 2;
+ CFX_RTFLine* pNextLine =
+ (m_pCurLine == &m_RTFLine1) ? &m_RTFLine2 : &m_RTFLine1;
+ FX_BOOL bAllChars = (m_iAlignment > FX_RTFLINEALIGNMENT_Right);
+ CFX_TPOArray tpos;
+ if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
+ goto EndBreak_Ret;
+ }
+ if (!m_bCharCode) {
+ EndBreak_BidiLine(tpos, dwStatus);
+ }
+ if (!m_bPagination && m_iAlignment > FX_RTFLINEALIGNMENT_Left) {
+ EndBreak_Alignment(tpos, bAllChars, dwStatus);
+ }
+EndBreak_Ret:
+ m_pCurLine = pNextLine;
+ m_pCurLine->m_iStart = m_iBoundaryStart;
+ CFX_RTFChar* pTC = GetLastChar(0);
+ m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
+ return dwStatus;
+}
+FX_BOOL CFX_RTFBreak::EndBreak_SplitLine(CFX_RTFLine* pNextLine,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus) {
+ FX_BOOL bDone = FALSE;
+ if (!m_bSingleLine && !m_bOrphanLine &&
+ m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) {
+ CFX_RTFChar& tc = m_pCurLine->GetChar(m_pCurLine->CountChars() - 1);
+ switch (tc.GetCharType()) {
+ case FX_CHARTYPE_Tab:
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ case FX_CHARTYPE_Control:
+ break;
+ case FX_CHARTYPE_Space:
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ default:
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ break;
+ }
+ }
+ if (m_bPagination || m_pCurLine->m_iMBCSChars > 0) {
+ const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.GetData();
+ const CFX_RTFChar* pTC;
+ CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
+ CFX_RTFPiece tp;
+ tp.m_pChars = &m_pCurLine->m_LineChars;
+ FX_BOOL bNew = TRUE;
+ FX_DWORD dwIdentity = (FX_DWORD)-1;
+ int32_t iLast = m_pCurLine->CountChars() - 1, j = 0;
+ for (int32_t i = 0; i <= iLast;) {
+ pTC = pCurChars + i;
+ if (bNew) {
+ tp.m_iStartChar = i;
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iWidth = 0;
+ tp.m_dwStatus = pTC->m_dwStatus;
+ tp.m_iFontSize = pTC->m_iFontSize;
+ tp.m_iFontHeight = pTC->m_iFontHeight;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ tp.m_dwLayoutStyles = pTC->m_dwLayoutStyles;
+ dwIdentity = pTC->m_dwIdentity;
+ tp.m_dwIdentity = dwIdentity;
+ tp.m_pUserData = pTC->m_pUserData;
+ j = i;
+ bNew = FALSE;
+ }
+ if (i == iLast || pTC->m_dwStatus != FX_RTFBREAK_None ||
+ pTC->m_dwIdentity != dwIdentity) {
+ tp.m_iChars = i - j;
+ if (pTC->m_dwIdentity == dwIdentity) {
+ tp.m_dwStatus = pTC->m_dwStatus;
+ tp.m_iWidth += pTC->m_iCharWidth;
+ tp.m_iChars += 1;
+ i++;
+ }
+ pCurPieces->Add(tp);
+ bNew = TRUE;
+ } else {
+ tp.m_iWidth += pTC->m_iCharWidth;
+ i++;
+ }
+ }
+ return TRUE;
+ }
+ if (bAllChars && !bDone) {
+ int32_t iEndPos = m_pCurLine->GetLineEnd();
+ GetBreakPos(m_pCurLine->m_LineChars, iEndPos, bAllChars, TRUE);
+ }
+ return FALSE;
+}
+void CFX_RTFBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus) {
+ FX_TPO tpo;
+ CFX_RTFPiece tp;
+ CFX_RTFChar* pTC;
+ int32_t i, j;
+ CFX_RTFCharArray& chars = m_pCurLine->m_LineChars;
+ int32_t iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = (!m_bPagination && !m_bCharCode &&
+ (m_pCurLine->m_iArabicChars > 0 || m_bRTL));
+ if (bDone) {
+ int32_t iBidiNum = 0;
+ for (i = 0; i < iCount; i++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiPos = i;
+ if (pTC->GetCharType() != FX_CHARTYPE_Control) {
+ iBidiNum = i;
+ }
+ if (i == 0) {
+ pTC->m_iBidiLevel = 1;
+ }
+ }
+ FX_BidiLine(chars, iBidiNum + 1, m_bRTL ? 1 : 0);
+ } else {
+ for (i = 0; i < iCount; i++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiLevel = 0;
+ pTC->m_iBidiPos = 0;
+ pTC->m_iBidiOrder = 0;
+ }
+ }
+ tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_pChars = &chars;
+ CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
+ int32_t iBidiLevel = -1, iCharWidth;
+ FX_DWORD dwIdentity = (FX_DWORD)-1;
+ i = j = 0;
+ while (i < iCount) {
+ pTC = chars.GetDataPtr(i);
+ if (iBidiLevel < 0) {
+ iBidiLevel = pTC->m_iBidiLevel;
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth < 1) {
+ tp.m_iWidth = 0;
+ } else {
+ tp.m_iWidth = iCharWidth;
+ }
+ tp.m_iBidiLevel = iBidiLevel;
+ tp.m_iBidiPos = pTC->m_iBidiOrder;
+ tp.m_iFontSize = pTC->m_iFontSize;
+ tp.m_iFontHeight = pTC->m_iFontHeight;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ dwIdentity = pTC->m_dwIdentity;
+ tp.m_dwIdentity = dwIdentity;
+ tp.m_pUserData = pTC->m_pUserData;
+ tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ i++;
+ } else if (iBidiLevel != pTC->m_iBidiLevel ||
+ pTC->m_dwIdentity != dwIdentity) {
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iStartChar = i;
+ tpo.index = j++;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ iBidiLevel = -1;
+ } else {
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i++;
+ }
+ }
+ if (i > tp.m_iStartChar) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tpo.index = j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ }
+ if (!m_bCharCode) {
+ j = tpos.GetSize() - 1;
+ FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
+ int32_t iStartPos = m_pCurLine->m_iStart;
+ for (i = 0; i <= j; i++) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
+ ttp.m_iStartPos = iStartPos;
+ iStartPos += ttp.m_iWidth;
+ }
+ }
+}
+void CFX_RTFBreak::EndBreak_Alignment(CFX_TPOArray& tpos,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus) {
+ CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
+ int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
+ int32_t iCount = pCurPieces->GetSize();
+ FX_BOOL bFind = FALSE;
+ FX_DWORD dwCharType;
+ int32_t i, j;
+ FX_TPO tpo;
+ for (i = iCount - 1; i > -1; i--) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
+ if (!bFind) {
+ iNetWidth = ttp.GetEndPos();
+ }
+ FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
+ j = bArabic ? 0 : ttp.m_iChars - 1;
+ while (j > -1 && j < ttp.m_iChars) {
+ const CFX_RTFChar& tc = ttp.GetChar(j);
+ if (tc.m_nBreakType == FX_LBT_DIRECT_BRK) {
+ iGapChars++;
+ }
+ if (!bFind || !bAllChars) {
+ dwCharType = tc.GetCharType();
+ if (dwCharType == FX_CHARTYPE_Space ||
+ dwCharType == FX_CHARTYPE_Control) {
+ if (!bFind) {
+ iCharWidth = tc.m_iCharWidth;
+ if (bAllChars && iCharWidth > 0) {
+ iNetWidth -= iCharWidth;
+ }
+ }
+ } else {
+ bFind = TRUE;
+ if (!bAllChars) {
+ break;
+ }
+ }
+ }
+ j += bArabic ? 1 : -1;
+ }
+ if (!bAllChars && bFind) {
+ break;
+ }
+ }
+ int32_t iOffset = m_iBoundaryEnd - iNetWidth;
+ int32_t iLowerAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_LowerMask);
+ int32_t iHigherAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_HigherMask);
+ if (iGapChars > 0 && (iHigherAlignment == FX_RTFLINEALIGNMENT_Distributed ||
+ (iHigherAlignment == FX_RTFLINEALIGNMENT_Justified &&
+ dwStatus != FX_RTFBREAK_ParagraphBreak))) {
+ int32_t iStart = -1;
+ for (i = 0; i < iCount; i++) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index);
+ if (iStart < 0) {
+ iStart = ttp.m_iStartPos;
+ } else {
+ ttp.m_iStartPos = iStart;
+ }
+ int32_t k;
+ for (j = 0; j < ttp.m_iChars; j++) {
+ CFX_RTFChar& tc = ttp.GetChar(j);
+ if (tc.m_nBreakType != FX_LBT_DIRECT_BRK || tc.m_iCharWidth < 0) {
+ continue;
+ }
+ k = iOffset / iGapChars;
+ tc.m_iCharWidth += k;
+ ttp.m_iWidth += k;
+ iOffset -= k;
+ iGapChars--;
+ if (iGapChars < 1) {
+ break;
+ }
+ }
+ iStart += ttp.m_iWidth;
+ }
+ } else if (iLowerAlignment > FX_RTFLINEALIGNMENT_Left) {
+ if (iLowerAlignment == FX_RTFLINEALIGNMENT_Center) {
+ iOffset /= 2;
+ }
+ if (iOffset > 0) {
+ for (i = 0; i < iCount; i++) {
+ CFX_RTFPiece& ttp = pCurPieces->GetAt(i);
+ ttp.m_iStartPos += iOffset;
+ }
+ }
+ }
+}
+int32_t CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray& tca,
+ int32_t& iEndPos,
+ FX_BOOL bAllChars,
+ FX_BOOL bOnlyBrk) {
+ int32_t iLength = tca.GetSize() - 1;
+ if (iLength < 1) {
+ return iLength;
+ }
+ int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1,
+ iLast = -1, iLastPos = -1;
+ if (m_bSingleLine || m_bOrphanLine || iEndPos <= m_iBoundaryEnd) {
+ if (!bAllChars || m_bCharCode) {
+ return iLength;
+ }
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ }
+ CFX_RTFChar* pCharArray = tca.GetData();
+ if (m_bCharCode) {
+ const CFX_RTFChar* pChar;
+ int32_t iCharWidth;
+ while (iLength > 0) {
+ if (iEndPos <= m_iBoundaryEnd) {
+ break;
+ }
+ pChar = pCharArray + iLength--;
+ iCharWidth = pChar->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ return iLength;
+ }
+ FX_BOOL bSpaceBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0;
+ FX_BOOL bTabBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0;
+ FX_BOOL bNumberBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_NumberBreak) != 0;
+ FX_BOOL bInfixBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_InfixBreak) != 0;
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD nCodeProp, nCur, nNext;
+ CFX_RTFChar* pCur = pCharArray + iLength--;
+ if (bAllChars) {
+ pCur->m_nBreakType = FX_LBT_UNKNOWN;
+ }
+ nCodeProp = pCur->m_dwCharProps;
+ nNext = nCodeProp & 0x003F;
+ int32_t iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ while (iLength >= 0) {
+ pCur = pCharArray + iLength;
+ nCodeProp = pCur->m_dwCharProps;
+ nCur = nCodeProp & 0x003F;
+ FX_BOOL bNeedBreak = FALSE;
+ if (nCur == FX_CBP_SP) {
+ bNeedBreak = !bSpaceBreak;
+ if (nNext == FX_CBP_SP) {
+ eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (nCur << 5) + nNext);
+ }
+ } else if (nCur == FX_CBP_TB) {
+ bNeedBreak = !bTabBreak;
+ if (nNext == FX_CBP_TB) {
+ eType = bTabBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (nCur << 5) + nNext);
+ }
+ } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else if (bInfixBreak && nCur == FX_CBP_IS && nNext == FX_CBP_IS) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else {
+ if (nNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (nCur << 5) + nNext);
+ }
+ }
+ if (bAllChars) {
+ pCur->m_nBreakType = eType;
+ }
+ if (!bOnlyBrk) {
+ iCharWidth = pCur->m_iCharWidth;
+ FX_BOOL bBreak = FALSE;
+ if (nCur == FX_CBP_TB && bTabBreak) {
+ bBreak = iCharWidth > 0 && iEndPos - iCharWidth <= m_iBoundaryEnd;
+ } else {
+ bBreak = iEndPos <= m_iBoundaryEnd;
+ }
+ if (m_bSingleLine || m_bOrphanLine || bBreak || bNeedBreak) {
+ if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ if (!bAllChars) {
+ return iLength;
+ }
+ } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
+ iIndirect = iLength;
+ iIndirectPos = iEndPos;
+ }
+ if (iLast < 0) {
+ iLast = iLength;
+ iLastPos = iEndPos;
+ }
+ }
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ nNext = nCodeProp & 0x003F;
+ iLength--;
+ }
+ if (bOnlyBrk) {
+ return 0;
+ }
+ if (iBreak > -1) {
+ iEndPos = iBreakPos;
+ return iBreak;
+ }
+ if (iIndirect > -1) {
+ iEndPos = iIndirectPos;
+ return iIndirect;
+ }
+ if (iLast > -1) {
+ iEndPos = iLastPos;
+ return iLast;
+ }
+ return 0;
+}
+void CFX_RTFBreak::SplitTextLine(CFX_RTFLine* pCurLine,
+ CFX_RTFLine* pNextLine,
+ FX_BOOL bAllChars) {
+ FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
+ int32_t iCount = pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ int32_t iEndPos = pCurLine->GetLineEnd();
+ CFX_RTFCharArray& curChars = pCurLine->m_LineChars;
+ int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
+ if (iCharPos < 0) {
+ iCharPos = 0;
+ }
+ iCharPos++;
+ if (iCharPos >= iCount) {
+ pNextLine->RemoveAll(TRUE);
+ CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ return;
+ }
+ CFX_RTFCharArray& nextChars = pNextLine->m_LineChars;
+ int cur_size = curChars.GetSize();
+ nextChars.SetSize(cur_size - iCharPos);
+ FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
+ (cur_size - iCharPos) * sizeof(CFX_RTFChar));
+ iCount -= iCharPos;
+ cur_size = curChars.GetSize();
+ curChars.RemoveAt(cur_size - iCount, iCount);
+ pNextLine->m_iStart = pCurLine->m_iStart;
+ pNextLine->m_iWidth = pCurLine->GetLineEnd() - iEndPos;
+ pCurLine->m_iWidth = iEndPos;
+ CFX_RTFChar* tc = curChars.GetDataPtr(iCharPos - 1);
+ tc->m_nBreakType = FX_LBT_UNKNOWN;
+ iCount = nextChars.GetSize();
+ CFX_RTFChar* pNextChars = nextChars.GetData();
+ for (int32_t i = 0; i < iCount; i++) {
+ CFX_RTFChar* tc = pNextChars + i;
+ if (tc->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
+ pCurLine->m_iArabicChars--;
+ pNextLine->m_iArabicChars++;
+ }
+ if (tc->m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) {
+ pCurLine->m_iMBCSChars--;
+ pNextLine->m_iMBCSChars++;
+ }
+ tc->m_dwStatus = 0;
+ }
+}
+int32_t CFX_RTFBreak::CountBreakPieces() const {
+ CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(TRUE);
+ if (pRTFPieces == NULL) {
+ return 0;
+ }
+ return pRTFPieces->GetSize();
+}
+const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(int32_t index) const {
+ CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(TRUE);
+ if (pRTFPieces == NULL) {
+ return NULL;
+ }
+ if (index < 0 || index >= pRTFPieces->GetSize()) {
+ return NULL;
+ }
+ return pRTFPieces->GetPtrAt(index);
+}
+void CFX_RTFBreak::GetLineRect(CFX_RectF& rect) const {
+ rect.top = 0;
+ CFX_RTFLine* pRTFLine = GetRTFLine(TRUE);
+ if (pRTFLine == NULL) {
+ rect.left = ((FX_FLOAT)m_iBoundaryStart) / 20000.0f;
+ rect.width = rect.height = 0;
+ return;
+ }
+ rect.left = ((FX_FLOAT)pRTFLine->m_iStart) / 20000.0f;
+ rect.width = ((FX_FLOAT)pRTFLine->m_iWidth) / 20000.0f;
+ CFX_RTFPieceArray& rtfPieces = pRTFLine->m_LinePieces;
+ int32_t iCount = rtfPieces.GetSize();
+ if (iCount < 1) {
+ rect.width = 0;
+ return;
+ }
+ CFX_RTFPiece* pBreakPiece;
+ int32_t iLineHeight = 0, iMax;
+ for (int32_t i = 0; i < iCount; i++) {
+ pBreakPiece = rtfPieces.GetPtrAt(i);
+ int32_t iFontHeight = FXSYS_round(pBreakPiece->m_iFontHeight *
+ pBreakPiece->m_iVerticalScale / 100.0f);
+ iMax = std::max(pBreakPiece->m_iFontSize, iFontHeight);
+ if (i == 0) {
+ iLineHeight = iMax;
+ } else if (iLineHeight < iMax) {
+ iLineHeight = iMax;
+ }
+ }
+ rect.height = ((FX_FLOAT)iLineHeight) / 20.0f;
+}
+void CFX_RTFBreak::ClearBreakPieces() {
+ CFX_RTFLine* pRTFLine = GetRTFLine(TRUE);
+ if (pRTFLine != NULL) {
+ pRTFLine->RemoveAll(TRUE);
+ }
+ m_iReady = 0;
+}
+void CFX_RTFBreak::Reset() {
+ m_dwCharType = 0;
+ m_RTFLine1.RemoveAll(TRUE);
+ m_RTFLine2.RemoveAll(TRUE);
+}
+int32_t CFX_RTFBreak::GetDisplayPos(FX_LPCRTFTEXTOBJ pText,
+ FXTEXT_CHARPOS* pCharPos,
+ FX_BOOL bCharCode,
+ CFX_WideString* pWSForms,
+ FX_AdjustCharDisplayPos pAdjustPos) const {
+ if (pText == NULL || pText->iLength < 1) {
+ return 0;
+ }
+ FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL &&
+ pText->pFont != NULL && pText->pRect != NULL);
+ const FX_WCHAR* pStr = pText->pStr;
+ int32_t* pWidths = pText->pWidths;
+ int32_t iLength = pText->iLength - 1;
+ IFX_Font* pFont = pText->pFont;
+ FX_DWORD dwStyles = pText->dwLayoutStyles;
+ CFX_RectF rtText(*pText->pRect);
+ FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
+ FX_FLOAT fFontSize = pText->fFontSize;
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ int32_t iAscent = pFont->GetAscent();
+ int32_t iDescent = pFont->GetDescent();
+ int32_t iMaxHeight = iAscent - iDescent;
+ FX_FLOAT fFontHeight = fFontSize;
+ FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
+ FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
+ FX_BOOL bVerticalDoc = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bVerticalChar = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
+ FX_BOOL bArabicNumber = (dwStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) != 0;
+ FX_BOOL bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
+ int32_t iRotation = GetLineRotation(dwStyles) + pText->iCharRotation;
+ int32_t iCharRotation;
+ FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm;
+ int32_t iWidth, iCharWidth, iCharHeight;
+ FX_FLOAT fX, fY, fCharWidth, fCharHeight;
+ int32_t iHorScale = pText->iHorizontalScale;
+ int32_t iVerScale = pText->iVerticalScale;
+ FX_BOOL bEmptyChar;
+ FX_DWORD dwProps, dwCharType;
+ fX = rtText.left;
+ fY = rtText.top;
+ if (bVerticalDoc) {
+ fX += (rtText.width - fFontSize) / 2.0f;
+ if (bRTLPiece) {
+ fY = rtText.bottom();
+ }
+ } else {
+ if (bRTLPiece) {
+ fX = rtText.right();
+ }
+ fY += fAscent;
+ }
+ int32_t iCount = 0;
+ for (int32_t i = 0; i <= iLength; i++) {
+ wch = *pStr++;
+ iWidth = *pWidths++;
+ if (!bMBCSCode) {
+ dwProps = FX_GetUnicodeProperties(wch);
+ dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
+ if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
+ wPrev = 0xFEFF;
+ continue;
+ }
+ } else {
+ dwProps = 0;
+ dwCharType = 0;
+ }
+ if (iWidth != 0) {
+ iCharWidth = iWidth;
+ if (iCharWidth < 0) {
+ iCharWidth = -iCharWidth;
+ }
+ if (!bMBCSCode) {
+ bEmptyChar = (dwCharType >= FX_CHARTYPE_Tab &&
+ dwCharType <= FX_CHARTYPE_Control);
+ } else {
+ bEmptyChar = FALSE;
+ }
+ if (!bEmptyChar) {
+ iCount++;
+ }
+ if (pCharPos != NULL) {
+ iCharWidth /= iFontSize;
+ wForm = wch;
+ if (!bMBCSCode) {
+ if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
+ if (i < iLength) {
+ wNext = *pStr;
+ if (*pWidths < 0) {
+ if (i + 1 < iLength) {
+ wNext = pStr[1];
+ }
+ }
+ } else {
+ wNext = 0xFEFF;
+ }
+ wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
+ } else if (bRTLPiece || bVerticalChar) {
+ wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
+ } else if (dwCharType == FX_CHARTYPE_Numeric && bArabicNumber) {
+ wForm = wch + 0x0630;
+ }
+ dwProps = FX_GetUnicodeProperties(wForm);
+ }
+ iCharRotation = iRotation;
+ if (!bMBCSCode && bVerticalChar && (dwProps & 0x8000) != 0) {
+ iCharRotation++;
+ iCharRotation %= 4;
+ }
+ if (!bEmptyChar) {
+ if (bCharCode) {
+ pCharPos->m_GlyphIndex = wch;
+ } else {
+ pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm, bMBCSCode);
+ if (pCharPos->m_GlyphIndex == 0xFFFF) {
+ pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch, bMBCSCode);
+ }
+ }
+ pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
+ pCharPos->m_FontCharWidth = iCharWidth;
+ if (pWSForms) {
+ *pWSForms += wForm;
+ }
+ }
+ if (bVerticalDoc) {
+ iCharHeight = iCharWidth;
+ iCharWidth = 1000;
+ } else {
+ iCharHeight = 1000;
+ }
+ fCharWidth = fFontSize * iCharWidth / 1000.0f;
+ fCharHeight = fFontSize * iCharHeight / 1000.0f;
+ if (!bMBCSCode && bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY -= fCharHeight;
+ } else {
+ fX -= fCharWidth;
+ }
+ }
+ if (!bEmptyChar) {
+ CFX_PointF ptOffset;
+ ptOffset.Reset();
+ FX_BOOL bAdjusted = FALSE;
+ if (pAdjustPos) {
+ bAdjusted = pAdjustPos(wForm, bMBCSCode, pFont, fFontSize,
+ bVerticalChar, ptOffset);
+ }
+ if (!pAdjustPos && bVerticalChar && (dwProps & 0x00010000) != 0) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, bMBCSCode)) {
+ ptOffset.x = fFontSize * (850 - rtBBox.right()) / 1000.0f;
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 2000.0f;
+ }
+ }
+ pCharPos->m_OriginX = fX + ptOffset.x;
+ pCharPos->m_OriginY = fY - ptOffset.y;
+ }
+ if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY += fCharHeight;
+ } else {
+ fX += fCharWidth;
+ }
+ }
+ if (!bEmptyChar) {
+ pCharPos->m_bGlyphAdjust = TRUE;
+ if (bVerticalDoc) {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent * iVerScale / 100.0f;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -=
+ fDescent + fAscent * iVerScale / 100.0f - fAscent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY += fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent;
+ pCharPos->m_OriginY += fCharWidth;
+ }
+ } else {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent * iVerScale / 100.0f - fAscent;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ pCharPos->m_OriginY -= fAscent + fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY -= fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent * iVerScale / 100.0f;
+ }
+ }
+ 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 (iWidth > 0) {
+ wPrev = wch;
+ }
+ }
+ return iCount;
+}
+int32_t CFX_RTFBreak::GetCharRects(FX_LPCRTFTEXTOBJ pText,
+ CFX_RectFArray& rtArray,
+ FX_BOOL bCharBBox) const {
+ if (pText == NULL || pText->iLength < 1) {
+ return 0;
+ }
+ FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL &&
+ pText->pFont != NULL && pText->pRect != NULL);
+ const FX_WCHAR* pStr = pText->pStr;
+ int32_t* pWidths = pText->pWidths;
+ int32_t iLength = pText->iLength;
+ CFX_RectF rect(*pText->pRect);
+ FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
+ FX_FLOAT fFontSize = pText->fFontSize;
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ IFX_Font* pFont = pText->pFont;
+ if (pFont == NULL) {
+ bCharBBox = FALSE;
+ }
+ CFX_Rect bbox;
+ bbox.Set(0, 0, 0, 0);
+ if (bCharBBox) {
+ bCharBBox = pFont->GetBBox(bbox);
+ }
+ FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
+ FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
+ rtArray.RemoveAll();
+ rtArray.SetSize(iLength);
+ FX_DWORD dwStyles = pText->dwLayoutStyles;
+ FX_BOOL bVertical = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bSingleLine = (dwStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
+ FX_BOOL bCombText = (dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ FX_WCHAR wch, wLineBreakChar = pText->wLineBreakChar;
+ int32_t iCharSize;
+ FX_FLOAT fCharSize, fStart;
+ if (bVertical) {
+ fStart = bRTLPiece ? rect.bottom() : rect.top;
+ } else {
+ fStart = bRTLPiece ? rect.right() : rect.left;
+ }
+ for (int32_t i = 0; i < iLength; i++) {
+ wch = *pStr++;
+ iCharSize = *pWidths++;
+ fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
+ FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
+ if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 ||
+ (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
+ bRet = FALSE;
+ }
+ if (bRet) {
+ iCharSize = iFontSize * 500;
+ fCharSize = fFontSize / 2.0f;
+ }
+ if (bVertical) {
+ rect.top = fStart;
+ if (bRTLPiece) {
+ rect.top -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.height = fCharSize;
+ } else {
+ rect.left = fStart;
+ if (bRTLPiece) {
+ rect.left -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.width = fCharSize;
+ }
+ if (bCharBBox && !bRet) {
+ int32_t iCharWidth = 1000;
+ pFont->GetCharWidth(wch, iCharWidth);
+ FX_FLOAT fRTLeft = 0, fCharWidth = 0;
+ if (iCharWidth > 0) {
+ fCharWidth = iCharWidth * fScale;
+ fRTLeft = fLeft;
+ if (bCombText) {
+ fRTLeft = (rect.width - fCharWidth) / 2.0f;
+ }
+ }
+ CFX_RectF rtBBoxF;
+ if (bVertical) {
+ rtBBoxF.top = rect.left + fRTLeft;
+ rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.height = fCharWidth;
+ rtBBoxF.width = fHeight;
+ rtBBoxF.left = std::max(rtBBoxF.left, 0.0f);
+ } else {
+ rtBBoxF.left = rect.left + fRTLeft;
+ rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.width = fCharWidth;
+ rtBBoxF.height = fHeight;
+ rtBBoxF.top = std::max(rtBBoxF.top, 0.0f);
+ }
+ rtArray.SetAt(i, rtBBoxF);
+ continue;
+ }
+ rtArray.SetAt(i, rect);
+ }
+ return iLength;
+}
diff --git a/xfa/src/fgas/src/layout/fx_rtfbreak.h b/xfa/src/fgas/src/layout/fx_rtfbreak.h
index 6addd52529..fbb955566a 100644
--- a/xfa/src/fgas/src/layout/fx_rtfbreak.h
+++ b/xfa/src/fgas/src/layout/fx_rtfbreak.h
@@ -1,174 +1,174 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_RTFBREAK_IMP
-#define _FX_RTFBREAK_IMP
-
-#include "core/include/fxcrt/fx_arb.h"
-
-class CFX_RTFLine;
-class CFX_RTFBreak;
-class CFX_RTFLine {
- public:
- CFX_RTFLine()
- : m_LinePieces(16),
- m_iStart(0),
- m_iWidth(0),
- m_iArabicChars(0),
- m_iMBCSChars(0) {}
- ~CFX_RTFLine() { RemoveAll(); }
- int32_t CountChars() const { return m_LineChars.GetSize(); }
- CFX_RTFChar& GetChar(int32_t index) {
- FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
- return *m_LineChars.GetDataPtr(index);
- }
- CFX_RTFChar* GetCharPtr(int32_t index) {
- FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
- return m_LineChars.GetDataPtr(index);
- }
- int32_t CountPieces() const { return m_LinePieces.GetSize(); }
- CFX_RTFPiece& GetPiece(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
- return m_LinePieces.GetAt(index);
- }
- CFX_RTFPiece* GetPiecePtr(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
- return m_LinePieces.GetPtrAt(index);
- }
- int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
- void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
- CFX_RTFChar* pChar;
- IFX_Unknown* pUnknown;
- int32_t iCount = m_LineChars.GetSize();
- for (int32_t i = 0; i < iCount; i++) {
- pChar = m_LineChars.GetDataPtr(i);
- if ((pUnknown = pChar->m_pUserData) != NULL) {
- pUnknown->Release();
- }
- }
- m_LineChars.RemoveAll();
- m_LinePieces.RemoveAll(bLeaveMemory);
- m_iWidth = 0;
- m_iArabicChars = 0;
- m_iMBCSChars = 0;
- }
- CFX_RTFCharArray m_LineChars;
- CFX_RTFPieceArray m_LinePieces;
- int32_t m_iStart;
- int32_t m_iWidth;
- int32_t m_iArabicChars;
- int32_t m_iMBCSChars;
-};
-class CFX_RTFBreak : public IFX_RTFBreak {
- public:
- CFX_RTFBreak(FX_DWORD dwPolicies);
- ~CFX_RTFBreak();
- void Release() override { delete this; }
- void SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) override final;
- void SetLineStartPos(FX_FLOAT fLinePos) override final;
- FX_DWORD GetLayoutStyles() const override { return m_dwLayoutStyles; }
- void SetLayoutStyles(FX_DWORD dwLayoutStyles) override;
- void SetFont(IFX_Font* pFont) override;
- void SetFontSize(FX_FLOAT fFontSize) override;
- void SetTabWidth(FX_FLOAT fTabWidth) override;
- void AddPositionedTab(FX_FLOAT fTabPos) override;
- void SetPositionedTabs(const CFX_FloatArray& tabs) override;
- void ClearPositionedTabs() override;
- void SetDefaultChar(FX_WCHAR wch) override;
- void SetLineBreakChar(FX_WCHAR wch) override;
- void SetLineBreakTolerance(FX_FLOAT fTolerance) override;
- void SetHorizontalScale(int32_t iScale) override;
- void SetVerticalScale(int32_t iScale) override;
- void SetCharRotation(int32_t iCharRotation) override;
- void SetCharSpace(FX_FLOAT fCharSpace) override;
- void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) override;
- void SetReadingOrder(FX_BOOL bRTL = FALSE) override;
- void SetAlignment(int32_t iAlignment = FX_RTFLINEALIGNMENT_Left) override;
- void SetUserData(IFX_Unknown* pUserData) override;
- FX_DWORD AppendChar(FX_WCHAR wch) override;
- FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak) override;
- int32_t CountBreakPieces() const override;
- const CFX_RTFPiece* GetBreakPiece(int32_t index) const override;
- void GetLineRect(CFX_RectF& rect) const override;
- void ClearBreakPieces() override;
- void Reset() override;
- int32_t GetDisplayPos(
- FX_LPCRTFTEXTOBJ pText,
- FXTEXT_CHARPOS* pCharPos,
- FX_BOOL bCharCode = FALSE,
- CFX_WideString* pWSForms = NULL,
- FX_AdjustCharDisplayPos pAdjustPos = NULL) const override;
- int32_t GetCharRects(FX_LPCRTFTEXTOBJ pText,
- CFX_RectFArray& rtArray,
- FX_BOOL bCharBBox = FALSE) const override;
- FX_DWORD AppendChar_CharCode(FX_WCHAR wch);
- FX_DWORD AppendChar_Combination(CFX_RTFChar* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Tab(CFX_RTFChar* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Control(CFX_RTFChar* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Arabic(CFX_RTFChar* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Others(CFX_RTFChar* pCurChar, int32_t iRotation);
-
- protected:
- FX_DWORD m_dwPolicies;
- IFX_ArabicChar* m_pArabicChar;
- int32_t m_iBoundaryStart;
- int32_t m_iBoundaryEnd;
- FX_DWORD m_dwLayoutStyles;
- FX_BOOL m_bPagination;
- FX_BOOL m_bVertical;
- FX_BOOL m_bSingleLine;
- FX_BOOL m_bCharCode;
- IFX_Font* m_pFont;
- int32_t m_iFontHeight;
- int32_t m_iFontSize;
- int32_t m_iTabWidth;
- CFX_Int32Array m_PositionedTabs;
- FX_BOOL m_bOrphanLine;
- FX_WCHAR m_wDefChar;
- int32_t m_iDefChar;
- FX_WCHAR m_wLineBreakChar;
- int32_t m_iHorizontalScale;
- int32_t m_iVerticalScale;
- int32_t m_iLineRotation;
- int32_t m_iCharRotation;
- int32_t m_iRotation;
- int32_t m_iCharSpace;
- FX_BOOL m_bWordSpace;
- int32_t m_iWordSpace;
- FX_BOOL m_bRTL;
- int32_t m_iAlignment;
- IFX_Unknown* m_pUserData;
- FX_DWORD m_dwCharType;
- FX_DWORD m_dwIdentity;
- CFX_RTFLine m_RTFLine1;
- CFX_RTFLine m_RTFLine2;
- CFX_RTFLine* m_pCurLine;
- int32_t m_iReady;
- int32_t m_iTolerance;
- int32_t GetLineRotation(FX_DWORD dwStyles) const;
- void SetBreakStatus();
- CFX_RTFChar* GetLastChar(int32_t index) const;
- CFX_RTFLine* GetRTFLine(FX_BOOL bReady) const;
- CFX_RTFPieceArray* GetRTFPieces(FX_BOOL bReady) const;
- FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
- int32_t GetLastPositionedTab() const;
- FX_BOOL GetPositionedTab(int32_t& iTabPos) const;
- int32_t GetBreakPos(CFX_RTFCharArray& tca,
- int32_t& iEndPos,
- FX_BOOL bAllChars = FALSE,
- FX_BOOL bOnlyBrk = FALSE);
- void SplitTextLine(CFX_RTFLine* pCurLine,
- CFX_RTFLine* pNextLine,
- FX_BOOL bAllChars = FALSE);
- FX_BOOL EndBreak_SplitLine(CFX_RTFLine* pNextLine,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus);
- void EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus);
- void EndBreak_Alignment(CFX_TPOArray& tpos,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus);
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_RTFBREAK_IMP
+#define _FX_RTFBREAK_IMP
+
+#include "core/include/fxcrt/fx_arb.h"
+
+class CFX_RTFLine;
+class CFX_RTFBreak;
+class CFX_RTFLine {
+ public:
+ CFX_RTFLine()
+ : m_LinePieces(16),
+ m_iStart(0),
+ m_iWidth(0),
+ m_iArabicChars(0),
+ m_iMBCSChars(0) {}
+ ~CFX_RTFLine() { RemoveAll(); }
+ int32_t CountChars() const { return m_LineChars.GetSize(); }
+ CFX_RTFChar& GetChar(int32_t index) {
+ FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
+ return *m_LineChars.GetDataPtr(index);
+ }
+ CFX_RTFChar* GetCharPtr(int32_t index) {
+ FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
+ return m_LineChars.GetDataPtr(index);
+ }
+ int32_t CountPieces() const { return m_LinePieces.GetSize(); }
+ CFX_RTFPiece& GetPiece(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
+ return m_LinePieces.GetAt(index);
+ }
+ CFX_RTFPiece* GetPiecePtr(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
+ return m_LinePieces.GetPtrAt(index);
+ }
+ int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ CFX_RTFChar* pChar;
+ IFX_Unknown* pUnknown;
+ int32_t iCount = m_LineChars.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ pChar = m_LineChars.GetDataPtr(i);
+ if ((pUnknown = pChar->m_pUserData) != NULL) {
+ pUnknown->Release();
+ }
+ }
+ m_LineChars.RemoveAll();
+ m_LinePieces.RemoveAll(bLeaveMemory);
+ m_iWidth = 0;
+ m_iArabicChars = 0;
+ m_iMBCSChars = 0;
+ }
+ CFX_RTFCharArray m_LineChars;
+ CFX_RTFPieceArray m_LinePieces;
+ int32_t m_iStart;
+ int32_t m_iWidth;
+ int32_t m_iArabicChars;
+ int32_t m_iMBCSChars;
+};
+class CFX_RTFBreak : public IFX_RTFBreak {
+ public:
+ CFX_RTFBreak(FX_DWORD dwPolicies);
+ ~CFX_RTFBreak();
+ void Release() override { delete this; }
+ void SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) override final;
+ void SetLineStartPos(FX_FLOAT fLinePos) override final;
+ FX_DWORD GetLayoutStyles() const override { return m_dwLayoutStyles; }
+ void SetLayoutStyles(FX_DWORD dwLayoutStyles) override;
+ void SetFont(IFX_Font* pFont) override;
+ void SetFontSize(FX_FLOAT fFontSize) override;
+ void SetTabWidth(FX_FLOAT fTabWidth) override;
+ void AddPositionedTab(FX_FLOAT fTabPos) override;
+ void SetPositionedTabs(const CFX_FloatArray& tabs) override;
+ void ClearPositionedTabs() override;
+ void SetDefaultChar(FX_WCHAR wch) override;
+ void SetLineBreakChar(FX_WCHAR wch) override;
+ void SetLineBreakTolerance(FX_FLOAT fTolerance) override;
+ void SetHorizontalScale(int32_t iScale) override;
+ void SetVerticalScale(int32_t iScale) override;
+ void SetCharRotation(int32_t iCharRotation) override;
+ void SetCharSpace(FX_FLOAT fCharSpace) override;
+ void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) override;
+ void SetReadingOrder(FX_BOOL bRTL = FALSE) override;
+ void SetAlignment(int32_t iAlignment = FX_RTFLINEALIGNMENT_Left) override;
+ void SetUserData(IFX_Unknown* pUserData) override;
+ FX_DWORD AppendChar(FX_WCHAR wch) override;
+ FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak) override;
+ int32_t CountBreakPieces() const override;
+ const CFX_RTFPiece* GetBreakPiece(int32_t index) const override;
+ void GetLineRect(CFX_RectF& rect) const override;
+ void ClearBreakPieces() override;
+ void Reset() override;
+ int32_t GetDisplayPos(
+ FX_LPCRTFTEXTOBJ pText,
+ FXTEXT_CHARPOS* pCharPos,
+ FX_BOOL bCharCode = FALSE,
+ CFX_WideString* pWSForms = NULL,
+ FX_AdjustCharDisplayPos pAdjustPos = NULL) const override;
+ int32_t GetCharRects(FX_LPCRTFTEXTOBJ pText,
+ CFX_RectFArray& rtArray,
+ FX_BOOL bCharBBox = FALSE) const override;
+ FX_DWORD AppendChar_CharCode(FX_WCHAR wch);
+ FX_DWORD AppendChar_Combination(CFX_RTFChar* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Tab(CFX_RTFChar* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Control(CFX_RTFChar* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Arabic(CFX_RTFChar* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Others(CFX_RTFChar* pCurChar, int32_t iRotation);
+
+ protected:
+ FX_DWORD m_dwPolicies;
+ IFX_ArabicChar* m_pArabicChar;
+ int32_t m_iBoundaryStart;
+ int32_t m_iBoundaryEnd;
+ FX_DWORD m_dwLayoutStyles;
+ FX_BOOL m_bPagination;
+ FX_BOOL m_bVertical;
+ FX_BOOL m_bSingleLine;
+ FX_BOOL m_bCharCode;
+ IFX_Font* m_pFont;
+ int32_t m_iFontHeight;
+ int32_t m_iFontSize;
+ int32_t m_iTabWidth;
+ CFX_Int32Array m_PositionedTabs;
+ FX_BOOL m_bOrphanLine;
+ FX_WCHAR m_wDefChar;
+ int32_t m_iDefChar;
+ FX_WCHAR m_wLineBreakChar;
+ int32_t m_iHorizontalScale;
+ int32_t m_iVerticalScale;
+ int32_t m_iLineRotation;
+ int32_t m_iCharRotation;
+ int32_t m_iRotation;
+ int32_t m_iCharSpace;
+ FX_BOOL m_bWordSpace;
+ int32_t m_iWordSpace;
+ FX_BOOL m_bRTL;
+ int32_t m_iAlignment;
+ IFX_Unknown* m_pUserData;
+ FX_DWORD m_dwCharType;
+ FX_DWORD m_dwIdentity;
+ CFX_RTFLine m_RTFLine1;
+ CFX_RTFLine m_RTFLine2;
+ CFX_RTFLine* m_pCurLine;
+ int32_t m_iReady;
+ int32_t m_iTolerance;
+ int32_t GetLineRotation(FX_DWORD dwStyles) const;
+ void SetBreakStatus();
+ CFX_RTFChar* GetLastChar(int32_t index) const;
+ CFX_RTFLine* GetRTFLine(FX_BOOL bReady) const;
+ CFX_RTFPieceArray* GetRTFPieces(FX_BOOL bReady) const;
+ FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
+ int32_t GetLastPositionedTab() const;
+ FX_BOOL GetPositionedTab(int32_t& iTabPos) const;
+ int32_t GetBreakPos(CFX_RTFCharArray& tca,
+ int32_t& iEndPos,
+ FX_BOOL bAllChars = FALSE,
+ FX_BOOL bOnlyBrk = FALSE);
+ void SplitTextLine(CFX_RTFLine* pCurLine,
+ CFX_RTFLine* pNextLine,
+ FX_BOOL bAllChars = FALSE);
+ FX_BOOL EndBreak_SplitLine(CFX_RTFLine* pNextLine,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus);
+ void EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus);
+ void EndBreak_Alignment(CFX_TPOArray& tpos,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus);
+};
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_textbreak.cpp b/xfa/src/fgas/src/layout/fx_textbreak.cpp
index a9ce859623..d36b477f3c 100644
--- a/xfa/src/fgas/src/layout/fx_textbreak.cpp
+++ b/xfa/src/fgas/src/layout/fx_textbreak.cpp
@@ -1,1661 +1,1661 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "core/include/fxcrt/fx_arb.h"
-#include "xfa/src/fgas/include/fx_lbk.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "xfa/src/fgas/src/layout/fx_unicode.h"
-#include "xfa/src/fgas/src/layout/fx_textbreak.h"
-
-extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32];
-IFX_TxtBreak* IFX_TxtBreak::Create(FX_DWORD dwPolicies) {
- return new CFX_TxtBreak(dwPolicies);
-}
-CFX_TxtBreak::CFX_TxtBreak(FX_DWORD dwPolicies)
- : m_dwPolicies(dwPolicies),
- m_pArabicChar(NULL),
- m_iLineWidth(2000000),
- m_dwLayoutStyles(0),
- m_bVertical(FALSE),
- m_bArabicContext(FALSE),
- m_bArabicShapes(FALSE),
- m_bRTL(FALSE),
- m_bSingleLine(FALSE),
- m_bCombText(FALSE),
- m_iArabicContext(1),
- m_iCurArabicContext(1),
- m_pFont(NULL),
- m_iFontSize(240),
- m_bEquidistant(TRUE),
- m_iTabWidth(720000),
- m_wDefChar(0xFEFF),
- m_wParagBreakChar(L'\n'),
- m_iDefChar(0),
- m_iLineRotation(0),
- m_iCharRotation(0),
- m_iRotation(0),
- m_iAlignment(FX_TXTLINEALIGNMENT_Left),
- m_dwContextCharStyles(0),
- m_iCombWidth(360000),
- m_pUserData(NULL),
- m_dwCharType(0),
- m_bArabicNumber(FALSE),
- m_bArabicComma(FALSE),
- m_pCurLine(NULL),
- m_iReady(0),
- m_iTolerance(0),
- m_iHorScale(100),
- m_iVerScale(100),
- m_iCharSpace(0) {
- m_bPagination = (m_dwPolicies & FX_TXTBREAKPOLICY_Pagination) != 0;
- m_pArabicChar = IFX_ArabicChar::Create();
- if (m_bPagination) {
- m_pTxtLine1 = new CFX_TxtLine(sizeof(CFX_Char));
- m_pTxtLine2 = new CFX_TxtLine(sizeof(CFX_Char));
- } else {
- m_pTxtLine1 = new CFX_TxtLine(sizeof(CFX_TxtChar));
- m_pTxtLine2 = new CFX_TxtLine(sizeof(CFX_TxtChar));
- }
- m_pCurLine = m_pTxtLine1;
- ResetArabicContext();
-}
-CFX_TxtBreak::~CFX_TxtBreak() {
- Reset();
- delete m_pTxtLine1;
- delete m_pTxtLine2;
- m_pArabicChar->Release();
-}
-void CFX_TxtBreak::SetLineWidth(FX_FLOAT fLineWidth) {
- m_iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
- FXSYS_assert(m_iLineWidth >= 20000);
-}
-void CFX_TxtBreak::SetLinePos(FX_FLOAT fLinePos) {
- int32_t iLinePos = FXSYS_round(fLinePos * 20000.0f);
- if (iLinePos < 0) {
- iLinePos = 0;
- }
- if (iLinePos > m_iLineWidth) {
- iLinePos = m_iLineWidth;
- }
- m_pCurLine->m_iStart = iLinePos;
- m_pCurLine->m_iWidth += iLinePos;
-}
-void CFX_TxtBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles) {
- m_dwLayoutStyles = dwLayoutStyles;
- m_bVertical = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
- m_bArabicContext = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicContext) != 0;
- m_bArabicShapes = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicShapes) != 0;
- m_bRTL = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_RTLReadingOrder) != 0;
- m_bSingleLine = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
- m_bCombText = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
- ResetArabicContext();
- m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
- m_iRotation = m_iLineRotation + m_iCharRotation;
- m_iRotation %= 4;
-}
-void CFX_TxtBreak::SetFont(IFX_Font* pFont) {
- if (pFont == NULL) {
- return;
- }
- if (m_pFont == pFont) {
- return;
- }
- SetBreakStatus();
- m_pFont = pFont;
- m_iDefChar = 0;
- if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- m_iDefChar *= m_iFontSize;
- }
-}
-void CFX_TxtBreak::SetFontSize(FX_FLOAT fFontSize) {
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- if (m_iFontSize == iFontSize) {
- return;
- }
- SetBreakStatus();
- m_iFontSize = iFontSize;
- m_iDefChar = 0;
- if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- m_iDefChar *= m_iFontSize;
- }
-}
-void CFX_TxtBreak::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
- m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
- if (m_iTabWidth < FX_TXTBREAK_MinimumTabWidth) {
- m_iTabWidth = FX_TXTBREAK_MinimumTabWidth;
- }
- m_bEquidistant = bEquidistant;
-}
-void CFX_TxtBreak::SetDefaultChar(FX_WCHAR wch) {
- m_wDefChar = wch;
- m_iDefChar = 0;
- if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
- m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
- if (m_iDefChar < 0) {
- m_iDefChar = 0;
- } else {
- m_iDefChar *= m_iFontSize;
- }
- }
-}
-void CFX_TxtBreak::SetParagraphBreakChar(FX_WCHAR wch) {
- if (wch != L'\r' && wch != L'\n') {
- return;
- }
- m_wParagBreakChar = wch;
-}
-void CFX_TxtBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) {
- m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
-}
-void CFX_TxtBreak::SetCharRotation(int32_t iCharRotation) {
- if (iCharRotation < 0) {
- iCharRotation += (-iCharRotation / 4 + 1) * 4;
- } else if (iCharRotation > 3) {
- iCharRotation -= (iCharRotation / 4) * 4;
- }
- if (m_iCharRotation == iCharRotation) {
- return;
- }
- SetBreakStatus();
- m_iCharRotation = iCharRotation;
- m_iRotation = m_iLineRotation + m_iCharRotation;
- m_iRotation %= 4;
-}
-void CFX_TxtBreak::SetAlignment(int32_t iAlignment) {
- FXSYS_assert(iAlignment >= FX_TXTLINEALIGNMENT_Left &&
- iAlignment <= FX_TXTLINEALIGNMENT_Distributed);
- m_iAlignment = iAlignment;
- ResetArabicContext();
-}
-void CFX_TxtBreak::ResetContextCharStyles() {
- m_dwContextCharStyles = m_bArabicContext ? m_iCurAlignment : m_iAlignment;
- if (m_bArabicNumber) {
- m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicNumber;
- }
- if (m_bArabicComma) {
- m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
- }
- if ((m_bArabicContext && m_bCurRTL) || (!m_bArabicContext && m_bRTL)) {
- m_dwContextCharStyles |= FX_TXTCHARSTYLE_RTLReadingOrder;
- }
- m_dwContextCharStyles |= (m_iArabicContext << 8);
-}
-FX_DWORD CFX_TxtBreak::GetContextCharStyles() const {
- return m_dwContextCharStyles;
-}
-void CFX_TxtBreak::SetContextCharStyles(FX_DWORD dwCharStyles) {
- m_iCurAlignment = dwCharStyles & 0x0F;
- m_bArabicNumber = (dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
- m_bArabicComma = (dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
- m_bCurRTL = (dwCharStyles & FX_TXTCHARSTYLE_RTLReadingOrder) != 0;
- m_iCurArabicContext = m_iArabicContext = ((dwCharStyles & 0x0300) >> 8);
- ResetContextCharStyles();
-}
-void CFX_TxtBreak::SetCombWidth(FX_FLOAT fCombWidth) {
- m_iCombWidth = FXSYS_round(fCombWidth * 20000.0f);
-}
-void CFX_TxtBreak::SetUserData(void* pUserData) {
- if (m_pUserData == pUserData) {
- return;
- }
- SetBreakStatus();
- m_pUserData = pUserData;
-}
-void CFX_TxtBreak::SetBreakStatus() {
- if (m_bPagination) {
- return;
- }
- int32_t iCount = m_pCurLine->CountChars();
- if (iCount < 1) {
- return;
- }
- CFX_TxtChar* pTC = (CFX_TxtChar*)m_pCurLine->GetCharPtr(iCount - 1);
- if (pTC->m_dwStatus == 0) {
- pTC->m_dwStatus = FX_TXTBREAK_PieceBreak;
- }
-}
-void CFX_TxtBreak::SetHorizontalScale(int32_t iScale) {
- if (iScale < 0) {
- iScale = 0;
- }
- if (iScale == m_iHorScale) {
- return;
- }
- SetBreakStatus();
- m_iHorScale = iScale;
-}
-void CFX_TxtBreak::SetVerticalScale(int32_t iScale) {
- if (iScale < 0) {
- iScale = 0;
- }
- if (iScale == m_iHorScale) {
- return;
- }
- SetBreakStatus();
- m_iVerScale = iScale;
-}
-void CFX_TxtBreak::SetCharSpace(FX_FLOAT fCharSpace) {
- m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
-}
-static const int32_t gs_FX_TxtLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
-int32_t CFX_TxtBreak::GetLineRotation(FX_DWORD dwStyles) const {
- return gs_FX_TxtLineRotations[(dwStyles & 0x0E) >> 1];
-}
-CFX_TxtChar* CFX_TxtBreak::GetLastChar(int32_t index, FX_BOOL bOmitChar) const {
- CFX_TxtCharArray& ca = *m_pCurLine->m_pLineChars;
- int32_t iCount = ca.GetSize();
- if (index < 0 || index >= iCount) {
- return NULL;
- }
- CFX_TxtChar* pTC;
- int32_t iStart = iCount - 1;
- while (iStart > -1) {
- pTC = ca.GetDataPtr(iStart--);
- if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) {
- continue;
- }
- if (--index < 0) {
- return pTC;
- }
- }
- return NULL;
-}
-CFX_TxtLine* CFX_TxtBreak::GetTxtLine(FX_BOOL bReady) const {
- if (!bReady) {
- return m_pCurLine;
- }
- if (m_iReady == 1) {
- return m_pTxtLine1;
- } else if (m_iReady == 2) {
- return m_pTxtLine2;
- } else {
- return NULL;
- }
-}
-CFX_TxtPieceArray* CFX_TxtBreak::GetTxtPieces(FX_BOOL bReady) const {
- CFX_TxtLine* pTxtLine = GetTxtLine(bReady);
- if (pTxtLine == NULL) {
- return NULL;
- }
- return pTxtLine->m_pLinePieces;
-}
-inline FX_DWORD CFX_TxtBreak::GetUnifiedCharType(FX_DWORD dwType) const {
- return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
-}
-void CFX_TxtBreak::ResetArabicContext() {
- if (m_bArabicContext) {
- m_bCurRTL = m_iCurArabicContext > 1;
- m_iCurAlignment = m_iCurArabicContext > 1 ? FX_TXTLINEALIGNMENT_Right
- : FX_TXTLINEALIGNMENT_Left;
- m_iCurAlignment |= (m_iAlignment & FX_TXTLINEALIGNMENT_HigherMask);
- m_bArabicNumber = m_iArabicContext >= 1 && m_bArabicShapes;
- } else {
- if (m_bPagination) {
- m_bCurRTL = FALSE;
- m_iCurAlignment = 0;
- } else {
- m_bCurRTL = m_bRTL;
- m_iCurAlignment = m_iAlignment;
- }
- if (m_bRTL) {
- m_bArabicNumber = m_iArabicContext >= 1;
- } else {
- m_bArabicNumber = m_iArabicContext > 1;
- }
- m_bArabicNumber = m_bArabicNumber && m_bArabicShapes;
- }
- m_bArabicComma = m_bArabicNumber;
- ResetContextCharStyles();
-}
-void CFX_TxtBreak::AppendChar_PageLoad(CFX_Char* pCurChar, FX_DWORD dwProps) {
- if (!m_bPagination) {
- ((CFX_TxtChar*)pCurChar)->m_dwStatus = 0;
- ((CFX_TxtChar*)pCurChar)->m_pUserData = m_pUserData;
- }
- if (m_bArabicContext || m_bArabicShapes) {
- int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
- int32_t iArabicContext =
- (iBidiCls == FX_BIDICLASS_R || iBidiCls == FX_BIDICLASS_AL)
- ? 2
- : ((iBidiCls == FX_BIDICLASS_L || iBidiCls == FX_BIDICLASS_S) ? 0
- : 1);
- if (iArabicContext != m_iArabicContext && iArabicContext != 1) {
- m_iArabicContext = iArabicContext;
- if (m_iCurArabicContext == 1) {
- m_iCurArabicContext = iArabicContext;
- }
- ResetArabicContext();
- if (!m_bPagination) {
- CFX_TxtChar* pLastChar = (CFX_TxtChar*)GetLastChar(1, FALSE);
- if (pLastChar != NULL && pLastChar->m_dwStatus < 1) {
- pLastChar->m_dwStatus = FX_TXTBREAK_PieceBreak;
- }
- }
- }
- }
- pCurChar->m_dwCharStyles = m_dwContextCharStyles;
-}
-FX_DWORD CFX_TxtBreak::AppendChar_Combination(CFX_Char* pCurChar,
- int32_t iRotation) {
- FXSYS_assert(pCurChar != NULL);
- FX_WCHAR wch = pCurChar->m_wCharCode;
- FX_WCHAR wForm;
- int32_t iCharWidth = 0;
- CFX_Char* pLastChar;
- pCurChar->m_iCharWidth = -1;
- if (m_bCombText) {
- iCharWidth = m_iCombWidth;
- } else {
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else {
- wForm = wch;
- if (!m_bPagination) {
- pLastChar = GetLastChar(0, FALSE);
- if (pLastChar != NULL &&
- (((CFX_TxtChar*)pLastChar)->m_dwCharStyles &
- FX_TXTCHARSTYLE_ArabicShadda) == 0) {
- FX_BOOL bShadda = FALSE;
- if (wch == 0x0651) {
- FX_WCHAR wLast = pLastChar->m_wCharCode;
- if (wLast >= 0x064C && wLast <= 0x0650) {
- wForm = FX_GetArabicFromShaddaTable(wLast);
- bShadda = TRUE;
- }
- } else if (wch >= 0x064C && wch <= 0x0650) {
- if (pLastChar->m_wCharCode == 0x0651) {
- wForm = FX_GetArabicFromShaddaTable(wch);
- bShadda = TRUE;
- }
- }
- if (bShadda) {
- ((CFX_TxtChar*)pLastChar)->m_dwCharStyles |=
- FX_TXTCHARSTYLE_ArabicShadda;
- ((CFX_TxtChar*)pLastChar)->m_iCharWidth = 0;
- ((CFX_TxtChar*)pCurChar)->m_dwCharStyles |=
- FX_TXTCHARSTYLE_ArabicShadda;
- }
- }
- }
- if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
- iCharWidth = 0;
- }
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorScale / 100;
- }
- pCurChar->m_iCharWidth = -iCharWidth;
- return FX_TXTBREAK_None;
-}
-FX_DWORD CFX_TxtBreak::AppendChar_Tab(CFX_Char* pCurChar, int32_t iRotation) {
- m_dwCharType = FX_CHARTYPE_Tab;
- if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) {
- return FX_TXTBREAK_None;
- }
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- int32_t iCharWidth;
- if (m_bCombText) {
- iCharWidth = m_iCombWidth;
- } else {
- if (m_bEquidistant) {
- iCharWidth = iLineWidth;
- iCharWidth = m_iTabWidth * (iCharWidth / m_iTabWidth + 1) - iCharWidth;
- if (iCharWidth < FX_TXTBREAK_MinimumTabWidth) {
- iCharWidth += m_iTabWidth;
- }
- } else {
- iCharWidth = m_iTabWidth;
- }
- }
- pCurChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- if (!m_bSingleLine && iLineWidth >= m_iLineWidth + m_iTolerance) {
- return EndBreak(FX_TXTBREAK_LineBreak);
- }
- return FX_TXTBREAK_None;
-}
-FX_DWORD CFX_TxtBreak::AppendChar_Control(CFX_Char* pCurChar,
- int32_t iRotation) {
- m_dwCharType = FX_CHARTYPE_Control;
- FX_DWORD dwRet = FX_TXTBREAK_None;
- if (!m_bSingleLine) {
- FX_WCHAR wch = pCurChar->m_wCharCode;
- switch (wch) {
- case L'\v':
- case 0x2028:
- dwRet = FX_TXTBREAK_LineBreak;
- break;
- case L'\f':
- dwRet = FX_TXTBREAK_PageBreak;
- break;
- case 0x2029:
- dwRet = FX_TXTBREAK_ParagraphBreak;
- break;
- default:
- if (wch == m_wParagBreakChar) {
- dwRet = FX_TXTBREAK_ParagraphBreak;
- }
- break;
- }
- if (dwRet != FX_TXTBREAK_None) {
- dwRet = EndBreak(dwRet);
- }
- }
- return dwRet;
-}
-FX_DWORD CFX_TxtBreak::AppendChar_Arabic(CFX_Char* pCurChar,
- int32_t iRotation) {
- FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- FX_WCHAR wForm;
- int32_t iCharWidth = 0;
- CFX_Char* pLastChar = NULL;
- FX_BOOL bAlef = FALSE;
- if (!m_bCombText && m_dwCharType >= FX_CHARTYPE_ArabicAlef &&
- m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
- pLastChar = GetLastChar(1);
- if (pLastChar != NULL) {
- iCharWidth = pLastChar->m_iCharWidth;
- if (iCharWidth > 0) {
- iLineWidth -= iCharWidth;
- }
- CFX_Char* pPrevChar = GetLastChar(2);
- wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
- bAlef = (wForm == 0xFEFF &&
- pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
- int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
- if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
- iLastRotation++;
- }
- if (m_bVertical != FX_IsOdd(iLastRotation)) {
- iCharWidth = 1000;
- } else {
- m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
- }
- if (wForm == 0xFEFF) {
- iCharWidth = m_iDefChar;
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorScale / 100;
- pLastChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- iCharWidth = 0;
- }
- }
- m_dwCharType = dwType;
- wForm = m_pArabicChar->GetFormChar(pCurChar, bAlef ? NULL : pLastChar, NULL);
- if (m_bCombText) {
- iCharWidth = m_iCombWidth;
- } else {
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else {
- m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
- }
- if (wForm == 0xFEFF) {
- iCharWidth = m_iDefChar;
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorScale / 100;
- }
- pCurChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- m_pCurLine->m_iArabicChars++;
- if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance) {
- return EndBreak(FX_TXTBREAK_LineBreak);
- }
- return FX_TXTBREAK_None;
-}
-FX_DWORD CFX_TxtBreak::AppendChar_Others(CFX_Char* pCurChar,
- int32_t iRotation) {
- FX_DWORD dwProps = pCurChar->m_dwCharProps;
- FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- int32_t iCharWidth = 0;
- m_dwCharType = dwType;
- FX_WCHAR wch = pCurChar->m_wCharCode;
- FX_WCHAR wForm = wch;
- if (dwType == FX_CHARTYPE_Numeric) {
- if (m_bArabicNumber) {
- wForm = wch + 0x0630;
- pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicIndic;
- }
- } else if (wch == L',') {
- if (m_bArabicShapes && m_iCurArabicContext > 0) {
- wForm = 0x060C;
- pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
- }
- } else if (m_bCurRTL || m_bVertical) {
- wForm = FX_GetMirrorChar(wch, dwProps, m_bCurRTL, m_bVertical);
- }
- if (m_bCombText) {
- iCharWidth = m_iCombWidth;
- } else {
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
- iCharWidth = m_iDefChar;
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorScale / 100;
- }
- iCharWidth += m_iCharSpace;
- pCurChar->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space ||
- (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0);
- if (!m_bSingleLine && bBreak && iLineWidth > m_iLineWidth + m_iTolerance) {
- return EndBreak(FX_TXTBREAK_LineBreak);
- }
- return FX_TXTBREAK_None;
-}
-typedef FX_DWORD (CFX_TxtBreak::*FX_TxtBreak_LPFAppendChar)(CFX_Char* pCurChar,
- int32_t iRotation);
-static const FX_TxtBreak_LPFAppendChar g_FX_TxtBreak_lpfAppendChar[16] = {
- &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Tab,
- &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Control,
- &CFX_TxtBreak::AppendChar_Combination, &CFX_TxtBreak::AppendChar_Others,
- &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Arabic,
- &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Arabic,
- &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Arabic,
- &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Others,
- &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Others,
-};
-FX_DWORD CFX_TxtBreak::AppendChar(FX_WCHAR wch) {
- FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
- FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
- CFX_TxtChar* pCurChar = m_pCurLine->m_pLineChars->AddSpace();
- pCurChar->m_wCharCode = (FX_WORD)wch;
- pCurChar->m_nRotation = m_iCharRotation;
- pCurChar->m_dwCharProps = dwProps;
- pCurChar->m_dwCharStyles = 0;
- pCurChar->m_iCharWidth = 0;
- pCurChar->m_iHorizontalScale = m_iHorScale;
- pCurChar->m_iVertialScale = m_iVerScale;
- pCurChar->m_dwStatus = 0;
- pCurChar->m_iBidiClass = 0;
- pCurChar->m_iBidiLevel = 0;
- pCurChar->m_iBidiPos = 0;
- pCurChar->m_iBidiOrder = 0;
- pCurChar->m_pUserData = NULL;
- AppendChar_PageLoad(pCurChar, dwProps);
- FX_DWORD dwRet1 = FX_TXTBREAK_None;
- if (dwType != FX_CHARTYPE_Combination &&
- GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
- if (m_dwCharType > 0 &&
- m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine) {
- if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
- dwRet1 = EndBreak(FX_TXTBREAK_LineBreak);
- int32_t iCount = m_pCurLine->CountChars();
- if (iCount > 0) {
- pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1);
- }
- }
- }
- }
- int32_t iRotation = m_iRotation;
- if (m_bVertical && (dwProps & 0x8000) != 0) {
- iRotation = (iRotation + 1) % 4;
- }
- FX_DWORD dwRet2 =
- (this->*g_FX_TxtBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(
- pCurChar, iRotation);
- return std::max(dwRet1, dwRet2);
-}
-void CFX_TxtBreak::EndBreak_UpdateArabicShapes() {
- FXSYS_assert(m_bArabicShapes);
- int32_t iCount = m_pCurLine->CountChars();
- if (iCount < 2) {
- return;
- }
- int32_t& iLineWidth = m_pCurLine->m_iWidth;
- CFX_Char *pCur, *pNext;
- pCur = m_pCurLine->GetCharPtr(0);
- FX_BOOL bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
- pCur = m_pCurLine->GetCharPtr(1);
- FX_WCHAR wch, wForm;
- FX_BOOL bNextNum;
- int32_t i = 1, iCharWidth, iRotation;
- do {
- i++;
- if (i < iCount) {
- pNext = m_pCurLine->GetCharPtr(i);
- bNextNum = (pNext->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
- } else {
- pNext = NULL;
- bNextNum = FALSE;
- }
- wch = pCur->m_wCharCode;
- if (wch == L'.') {
- if (bPrevNum && bNextNum) {
- iRotation = m_iRotation;
- if (m_bVertical && (pCur->m_dwCharProps & 0x8000) != 0) {
- iRotation = ((iRotation + 1) & 0x03);
- }
- wForm = wch == L'.' ? 0x066B : 0x066C;
- iLineWidth -= pCur->m_iCharWidth;
- if (m_bCombText) {
- iCharWidth = m_iCombWidth;
- } else {
- if (m_bVertical != FX_IsOdd(iRotation)) {
- iCharWidth = 1000;
- } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
- iCharWidth = m_iDefChar;
- }
- iCharWidth *= m_iFontSize;
- iCharWidth = iCharWidth * m_iHorScale / 100;
- }
- pCur->m_iCharWidth = iCharWidth;
- iLineWidth += iCharWidth;
- }
- }
- bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
- pCur = pNext;
- } while (i < iCount);
-}
-FX_BOOL CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus) {
- int32_t iCount = m_pCurLine->CountChars();
- FX_BOOL bDone = FALSE;
- CFX_Char* pTC;
- if (!m_bSingleLine && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance) {
- pTC = m_pCurLine->GetCharPtr(iCount - 1);
- switch (pTC->GetCharType()) {
- case FX_CHARTYPE_Tab:
- case FX_CHARTYPE_Control:
- break;
- case FX_CHARTYPE_Space:
- if ((m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0) {
- SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
- bDone = TRUE;
- }
- break;
- default:
- SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
- bDone = TRUE;
- break;
- }
- }
- iCount = m_pCurLine->CountChars();
- CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
- CFX_TxtPiece tp;
- if (m_bPagination) {
- tp.m_dwStatus = dwStatus;
- tp.m_iStartPos = m_pCurLine->m_iStart;
- tp.m_iWidth = m_pCurLine->m_iWidth;
- tp.m_iStartChar = 0;
- tp.m_iChars = iCount;
- tp.m_pChars = m_pCurLine->m_pLineChars;
- tp.m_pUserData = m_pUserData;
- pTC = m_pCurLine->GetCharPtr(0);
- tp.m_dwCharStyles = pTC->m_dwCharStyles;
- tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
- tp.m_iVerticalScale = pTC->m_iVertialScale;
- pCurPieces->Add(tp);
- m_pCurLine = pNextLine;
- m_dwCharType = 0;
- return TRUE;
- }
- if (bAllChars && !bDone) {
- int32_t iEndPos = m_pCurLine->m_iWidth;
- GetBreakPos(*m_pCurLine->m_pLineChars, iEndPos, bAllChars, TRUE);
- }
- return FALSE;
-}
-void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus) {
- CFX_TxtPiece tp;
- FX_TPO tpo;
- CFX_TxtChar* pTC;
- int32_t i, j;
- CFX_TxtCharArray& chars = *m_pCurLine->m_pLineChars;
- int32_t iCount = m_pCurLine->CountChars();
- FX_BOOL bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL);
- if (!m_bPagination && bDone) {
- int32_t iBidiNum = 0;
- for (i = 0; i < iCount; i++) {
- pTC = chars.GetDataPtr(i);
- pTC->m_iBidiPos = i;
- if (pTC->GetCharType() != FX_CHARTYPE_Control) {
- iBidiNum = i;
- }
- if (i == 0) {
- pTC->m_iBidiLevel = 1;
- }
- }
- FX_BidiLine(chars, iBidiNum + 1, m_bCurRTL ? 1 : 0);
- }
- CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
- if (!m_bPagination &&
- (bDone || (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_MutipleFormat) != 0)) {
- tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
- tp.m_iStartPos = m_pCurLine->m_iStart;
- tp.m_pChars = m_pCurLine->m_pLineChars;
- int32_t iBidiLevel = -1, iCharWidth;
- i = 0, j = -1;
- while (i < iCount) {
- pTC = chars.GetDataPtr(i);
- if (iBidiLevel < 0) {
- iBidiLevel = pTC->m_iBidiLevel;
- tp.m_iWidth = 0;
- tp.m_iBidiLevel = iBidiLevel;
- tp.m_iBidiPos = pTC->m_iBidiOrder;
- tp.m_dwCharStyles = pTC->m_dwCharStyles;
- tp.m_pUserData = pTC->m_pUserData;
- tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
- tp.m_iVerticalScale = pTC->m_iVertialScale;
- tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
- }
- if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwStatus != 0) {
- if (iBidiLevel == pTC->m_iBidiLevel) {
- tp.m_dwStatus = pTC->m_dwStatus;
- iCharWidth = pTC->m_iCharWidth;
- if (iCharWidth > 0) {
- tp.m_iWidth += iCharWidth;
- }
- i++;
- }
- tp.m_iChars = i - tp.m_iStartChar;
- pCurPieces->Add(tp);
- tp.m_iStartPos += tp.m_iWidth;
- tp.m_iStartChar = i;
- tpo.index = ++j;
- tpo.pos = tp.m_iBidiPos;
- tpos.Add(tpo);
- iBidiLevel = -1;
- } else {
- iCharWidth = pTC->m_iCharWidth;
- if (iCharWidth > 0) {
- tp.m_iWidth += iCharWidth;
- }
- i++;
- }
- }
- if (i > tp.m_iStartChar) {
- tp.m_dwStatus = dwStatus;
- tp.m_iChars = i - tp.m_iStartChar;
- pCurPieces->Add(tp);
- tpo.index = ++j;
- tpo.pos = tp.m_iBidiPos;
- tpos.Add(tpo);
- }
- if (j > -1) {
- if (j > 0) {
- FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
- int32_t iStartPos = 0;
- for (i = 0; i <= j; i++) {
- tpo = tpos.GetAt(i);
- CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
- ttp.m_iStartPos = iStartPos;
- iStartPos += ttp.m_iWidth;
- }
- }
- CFX_TxtPiece& ttp = pCurPieces->GetAt(j);
- ttp.m_dwStatus = dwStatus;
- }
- } else {
- tp.m_dwStatus = dwStatus;
- tp.m_iStartPos = m_pCurLine->m_iStart;
- tp.m_iWidth = m_pCurLine->m_iWidth;
- tp.m_iStartChar = 0;
- tp.m_iChars = iCount;
- tp.m_pChars = m_pCurLine->m_pLineChars;
- tp.m_pUserData = m_pUserData;
- pTC = chars.GetDataPtr(0);
- tp.m_dwCharStyles = pTC->m_dwCharStyles;
- tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
- tp.m_iVerticalScale = pTC->m_iVertialScale;
- pCurPieces->Add(tp);
- tpo.index = 0;
- tpo.pos = 0;
- tpos.Add(tpo);
- }
-}
-void CFX_TxtBreak::EndBreak_Alignment(CFX_TPOArray& tpos,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus) {
- int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
- CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
- int32_t i, j, iCount = pCurPieces->GetSize();
- FX_BOOL bFind = FALSE;
- FX_TPO tpo;
- CFX_TxtChar* pTC;
- FX_DWORD dwCharType;
- for (i = iCount - 1; i > -1; i--) {
- tpo = tpos.GetAt(i);
- CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
- if (!bFind) {
- iNetWidth = ttp.GetEndPos();
- }
- FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
- j = bArabic ? 0 : ttp.m_iChars - 1;
- while (j > -1 && j < ttp.m_iChars) {
- pTC = ttp.GetCharPtr(j);
- if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK) {
- iGapChars++;
- }
- if (!bFind || !bAllChars) {
- dwCharType = pTC->GetCharType();
- if (dwCharType == FX_CHARTYPE_Space ||
- dwCharType == FX_CHARTYPE_Control) {
- if (!bFind) {
- iCharWidth = pTC->m_iCharWidth;
- if (bAllChars && iCharWidth > 0) {
- iNetWidth -= iCharWidth;
- }
- }
- } else {
- bFind = TRUE;
- if (!bAllChars) {
- break;
- }
- }
- }
- j += bArabic ? 1 : -1;
- }
- if (!bAllChars && bFind) {
- break;
- }
- }
- int32_t iOffset = m_iLineWidth - iNetWidth;
- int32_t iLowerAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_LowerMask);
- int32_t iHigherAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_HigherMask);
- if (iGapChars > 0 && (iHigherAlignment == FX_TXTLINEALIGNMENT_Distributed ||
- (iHigherAlignment == FX_TXTLINEALIGNMENT_Justified &&
- dwStatus != FX_TXTBREAK_ParagraphBreak))) {
- int32_t iStart = -1;
- for (i = 0; i < iCount; i++) {
- tpo = tpos.GetAt(i);
- CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
- if (iStart < -1) {
- iStart = ttp.m_iStartPos;
- } else {
- ttp.m_iStartPos = iStart;
- }
- int32_t k;
- for (j = 0; j < ttp.m_iChars; j++) {
- pTC = ttp.GetCharPtr(j);
- if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0) {
- continue;
- }
- k = iOffset / iGapChars;
- pTC->m_iCharWidth += k;
- ttp.m_iWidth += k;
- iOffset -= k;
- iGapChars--;
- if (iGapChars < 1) {
- break;
- }
- }
- iStart += ttp.m_iWidth;
- }
- } else if (iLowerAlignment > FX_TXTLINEALIGNMENT_Left) {
- if (iLowerAlignment == FX_TXTLINEALIGNMENT_Center) {
- iOffset /= 2;
- }
- if (iOffset > 0) {
- for (i = 0; i < iCount; i++) {
- CFX_TxtPiece& ttp = pCurPieces->GetAt(i);
- ttp.m_iStartPos += iOffset;
- }
- }
- }
-}
-FX_DWORD CFX_TxtBreak::EndBreak(FX_DWORD dwStatus) {
- FXSYS_assert(dwStatus >= FX_TXTBREAK_PieceBreak &&
- dwStatus <= FX_TXTBREAK_PageBreak);
- CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
- int32_t iCount = pCurPieces->GetSize();
- if (iCount > 0) {
- CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount);
- if (dwStatus > FX_TXTBREAK_PieceBreak) {
- pLastPiece->m_dwStatus = dwStatus;
- } else {
- dwStatus = pLastPiece->m_dwStatus;
- }
- return dwStatus;
- } else {
- CFX_TxtLine* pLastLine = GetTxtLine(TRUE);
- if (pLastLine != NULL) {
- pCurPieces = pLastLine->m_pLinePieces;
- iCount = pCurPieces->GetSize();
- if (iCount-- > 0) {
- CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(iCount);
- if (dwStatus > FX_TXTBREAK_PieceBreak) {
- pLastPiece->m_dwStatus = dwStatus;
- } else {
- dwStatus = pLastPiece->m_dwStatus;
- }
- return dwStatus;
- }
- return FX_TXTBREAK_None;
- }
- iCount = m_pCurLine->CountChars();
- if (iCount < 1) {
- return FX_TXTBREAK_None;
- }
- if (!m_bPagination) {
- CFX_TxtChar* pTC = m_pCurLine->GetCharPtr(iCount - 1);
- pTC->m_dwStatus = dwStatus;
- }
- if (dwStatus <= FX_TXTBREAK_PieceBreak) {
- return dwStatus;
- }
- }
- m_iReady = (m_pCurLine == m_pTxtLine1) ? 1 : 2;
- CFX_TxtLine* pNextLine =
- (m_pCurLine == m_pTxtLine1) ? m_pTxtLine2 : m_pTxtLine1;
- FX_BOOL bAllChars = (m_iCurAlignment > FX_TXTLINEALIGNMENT_Right);
- CFX_TPOArray tpos;
- CFX_Char* pTC;
- if (m_bArabicShapes) {
- EndBreak_UpdateArabicShapes();
- }
- if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
- goto EndBreak_Ret;
- }
- EndBreak_BidiLine(tpos, dwStatus);
- if (!m_bPagination && m_iCurAlignment > FX_TXTLINEALIGNMENT_Left) {
- EndBreak_Alignment(tpos, bAllChars, dwStatus);
- }
-EndBreak_Ret:
- m_pCurLine = pNextLine;
- pTC = GetLastChar(0, FALSE);
- m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
- if (dwStatus == FX_TXTBREAK_ParagraphBreak) {
- m_iArabicContext = m_iCurArabicContext = 1;
- ResetArabicContext();
- }
- return dwStatus;
-}
-int32_t CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray& ca,
- int32_t& iEndPos,
- FX_BOOL bAllChars,
- FX_BOOL bOnlyBrk) {
- int32_t iLength = ca.GetSize() - 1;
- if (iLength < 1) {
- return iLength;
- }
- int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1,
- iLast = -1, iLastPos = -1;
- if (m_bSingleLine || iEndPos <= m_iLineWidth) {
- if (!bAllChars) {
- return iLength;
- }
- iBreak = iLength;
- iBreakPos = iEndPos;
- }
- FX_BOOL bSpaceBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0;
- FX_BOOL bNumberBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_NumberBreak) != 0;
- FX_LINEBREAKTYPE eType;
- FX_DWORD nCodeProp, nCur, nNext;
- CFX_Char* pCur = ca.GetDataPtr(iLength--);
- if (bAllChars) {
- pCur->m_nBreakType = FX_LBT_UNKNOWN;
- }
- nCodeProp = pCur->m_dwCharProps;
- nNext = nCodeProp & 0x003F;
- int32_t iCharWidth = pCur->m_iCharWidth;
- if (iCharWidth > 0) {
- iEndPos -= iCharWidth;
- }
- while (iLength >= 0) {
- pCur = ca.GetDataPtr(iLength);
- nCodeProp = pCur->m_dwCharProps;
- nCur = nCodeProp & 0x003F;
- if (nCur == FX_CBP_SP) {
- if (nNext == FX_CBP_SP) {
- eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (nCur << 5) + nNext);
- }
- } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
- eType = FX_LBT_DIRECT_BRK;
- } else {
- if (nNext == FX_CBP_SP) {
- eType = FX_LBT_PROHIBITED_BRK;
- } else {
- eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
- (nCur << 5) + nNext);
- }
- }
- if (bAllChars) {
- pCur->m_nBreakType = (uint8_t)eType;
- }
- if (!bOnlyBrk) {
- if (m_bSingleLine || iEndPos <= m_iLineWidth ||
- (nCur == FX_CBP_SP && !bSpaceBreak)) {
- if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
- iBreak = iLength;
- iBreakPos = iEndPos;
- if (!bAllChars) {
- return iLength;
- }
- } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
- iIndirect = iLength;
- iIndirectPos = iEndPos;
- }
- if (iLast < 0) {
- iLast = iLength;
- iLastPos = iEndPos;
- }
- }
- iCharWidth = pCur->m_iCharWidth;
- if (iCharWidth > 0) {
- iEndPos -= iCharWidth;
- }
- }
- nNext = nCodeProp & 0x003F;
- iLength--;
- }
- if (bOnlyBrk) {
- return 0;
- }
- if (iBreak > -1) {
- iEndPos = iBreakPos;
- return iBreak;
- }
- if (iIndirect > -1) {
- iEndPos = iIndirectPos;
- return iIndirect;
- }
- if (iLast > -1) {
- iEndPos = iLastPos;
- return iLast;
- }
- return 0;
-}
-void CFX_TxtBreak::SplitTextLine(CFX_TxtLine* pCurLine,
- CFX_TxtLine* pNextLine,
- FX_BOOL bAllChars) {
- FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
- int32_t iCount = pCurLine->CountChars();
- if (iCount < 2) {
- return;
- }
- int32_t iEndPos = pCurLine->m_iWidth;
- CFX_TxtCharArray& curChars = *pCurLine->m_pLineChars;
- int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
- if (iCharPos < 0) {
- iCharPos = 0;
- }
- iCharPos++;
- if (iCharPos >= iCount) {
- pNextLine->RemoveAll(TRUE);
- CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
- pTC->m_nBreakType = FX_LBT_UNKNOWN;
- return;
- }
- CFX_TxtCharArray& nextChars = *pNextLine->m_pLineChars;
- int cur_size = curChars.GetSize();
- nextChars.SetSize(cur_size - iCharPos);
- FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
- (cur_size - iCharPos) * sizeof(CFX_TxtChar));
- iCount -= iCharPos;
- cur_size = curChars.GetSize();
- curChars.RemoveAt(cur_size - iCount, iCount);
- pCurLine->m_iWidth = iEndPos;
- CFX_TxtChar* pTC = curChars.GetDataPtr(iCharPos - 1);
- pTC->m_nBreakType = FX_LBT_UNKNOWN;
- iCount = nextChars.GetSize();
- int32_t iCharWidth, iWidth = 0;
- for (int32_t i = 0; i < iCount; i++) {
- pTC = nextChars.GetDataPtr(i);
- if (pTC->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
- pCurLine->m_iArabicChars--;
- pNextLine->m_iArabicChars++;
- }
- iCharWidth = pTC->m_iCharWidth;
- if (iCharWidth > 0) {
- iWidth += iCharWidth;
- }
- if (m_bPagination) {
- continue;
- }
- pTC->m_dwStatus = 0;
- }
- pNextLine->m_iWidth = iWidth;
-}
-int32_t CFX_TxtBreak::CountBreakChars() const {
- CFX_TxtLine* pTxtLine = GetTxtLine(TRUE);
- return pTxtLine == NULL ? 0 : pTxtLine->CountChars();
-}
-int32_t CFX_TxtBreak::CountBreakPieces() const {
- CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(TRUE);
- if (pTxtPieces == NULL) {
- return 0;
- }
- return pTxtPieces->GetSize();
-}
-const CFX_TxtPiece* CFX_TxtBreak::GetBreakPiece(int32_t index) const {
- CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(TRUE);
- if (pTxtPieces == NULL) {
- return NULL;
- }
- if (index < 0 || index >= pTxtPieces->GetSize()) {
- return NULL;
- }
- return pTxtPieces->GetPtrAt(index);
-}
-void CFX_TxtBreak::ClearBreakPieces() {
- CFX_TxtLine* pTxtLine = GetTxtLine(TRUE);
- if (pTxtLine != NULL) {
- pTxtLine->RemoveAll(TRUE);
- }
- m_iReady = 0;
-}
-void CFX_TxtBreak::Reset() {
- m_dwCharType = 0;
- m_iArabicContext = m_iCurArabicContext = 1;
- ResetArabicContext();
- m_pTxtLine1->RemoveAll(TRUE);
- m_pTxtLine2->RemoveAll(TRUE);
-}
-typedef struct _FX_FORMCHAR {
- FX_WORD wch;
- FX_WORD wForm;
- int32_t iWidth;
-} FX_FORMCHAR, *FX_LPFORMCHAR;
-typedef FX_FORMCHAR const* FX_LPCFORMCHAR;
-int32_t CFX_TxtBreak::GetDisplayPos(FX_LPCTXTRUN pTxtRun,
- FXTEXT_CHARPOS* pCharPos,
- FX_BOOL bCharCode,
- CFX_WideString* pWSForms,
- FX_AdjustCharDisplayPos pAdjustPos) const {
- if (pTxtRun == NULL || pTxtRun->iLength < 1) {
- return 0;
- }
- IFX_TxtAccess* pAccess = pTxtRun->pAccess;
- void* pIdentity = pTxtRun->pIdentity;
- const FX_WCHAR* pStr = pTxtRun->pStr;
- int32_t* pWidths = pTxtRun->pWidths;
- int32_t iLength = pTxtRun->iLength - 1;
- IFX_Font* pFont = pTxtRun->pFont;
- FX_DWORD dwStyles = pTxtRun->dwStyles;
- CFX_RectF rtText(*pTxtRun->pRect);
- FX_BOOL bRTLPiece =
- (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
- FX_BOOL bArabicNumber =
- (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
- FX_BOOL bArabicComma =
- (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
- FX_FLOAT fFontSize = pTxtRun->fFontSize;
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- int32_t iAscent = pFont->GetAscent();
- int32_t iDescent = pFont->GetDescent();
- int32_t iMaxHeight = iAscent - iDescent;
- FX_FLOAT fFontHeight = fFontSize;
- FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
- FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
- FX_BOOL bVerticalDoc = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
- FX_BOOL bVerticalChar = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
- int32_t iRotation = GetLineRotation(dwStyles) + pTxtRun->iCharRotation;
- int32_t iCharRotation;
- FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm, wLast = 0xFEFF;
- int32_t iWidth, iCharWidth, iCharHeight;
- FX_FLOAT fX, fY, fCharWidth, fCharHeight;
- int32_t iHorScale = pTxtRun->iHorizontalScale;
- int32_t iVerScale = pTxtRun->iVerticalScale;
- FX_BOOL bSkipSpace = pTxtRun->bSkipSpace;
- FX_BOOL bEmptyChar, bShadda = FALSE, bLam = FALSE;
- FX_DWORD dwProps, dwCharType;
- FX_FORMCHAR formChars[3];
- FX_FLOAT fYBase;
- fX = rtText.left;
- if (bVerticalDoc) {
- fX += (rtText.width - fFontSize) / 2.0f;
- fYBase = bRTLPiece ? rtText.bottom() : rtText.top;
- fY = fYBase;
- } else {
- if (bRTLPiece) {
- fX = rtText.right();
- }
- fYBase = rtText.top + (rtText.height - fFontSize) / 2.0f;
- fY = fYBase + fAscent;
- }
- int32_t iCount = 0, iNext, iForms;
- for (int32_t i = 0; i <= iLength; i++) {
- if (pAccess != NULL) {
- wch = pAccess->GetChar(pIdentity, i);
- iWidth = pAccess->GetWidth(pIdentity, i);
- } else {
- wch = *pStr++;
- iWidth = *pWidths++;
- }
- dwProps = FX_GetUnicodeProperties(wch);
- dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
- if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
- wPrev = 0xFEFF;
- wLast = wch;
- continue;
- }
- if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
- if (i < iLength) {
- if (pAccess != NULL) {
- iNext = i + 1;
- while (iNext <= iLength) {
- wNext = pAccess->GetChar(pIdentity, iNext);
- dwProps = FX_GetUnicodeProperties(wNext);
- if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination) {
- break;
- }
- iNext++;
- }
- if (iNext > iLength) {
- wNext = 0xFEFF;
- }
- } else {
- int32_t j = -1;
- do {
- j++;
- if (i + j >= iLength) {
- break;
- }
- wNext = pStr[j];
- dwProps = FX_GetUnicodeProperties(wNext);
- } while ((dwProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination);
- if (i + j >= iLength) {
- wNext = 0xFEFF;
- }
- }
- } else {
- wNext = 0xFEFF;
- }
- wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
- bLam = (wPrev == 0x0644 && wch == 0x0644 && wNext == 0x0647);
- } else if (dwCharType == FX_CHARTYPE_Combination) {
- wForm = wch;
- if (wch >= 0x064C && wch <= 0x0651) {
- if (bShadda) {
- wForm = 0xFEFF;
- bShadda = FALSE;
- } else {
- wNext = 0xFEFF;
- if (pAccess != NULL) {
- iNext = i + 1;
- if (iNext <= iLength) {
- wNext = pAccess->GetChar(pIdentity, iNext);
- }
- } else {
- if (i < iLength) {
- wNext = *pStr;
- }
- }
- if (wch == 0x0651) {
- if (wNext >= 0x064C && wNext <= 0x0650) {
- wForm = FX_GetArabicFromShaddaTable(wNext);
- bShadda = TRUE;
- }
- } else {
- if (wNext == 0x0651) {
- wForm = FX_GetArabicFromShaddaTable(wch);
- bShadda = TRUE;
- }
- }
- }
- } else {
- bShadda = FALSE;
- }
- } else if (dwCharType == FX_CHARTYPE_Numeric) {
- wForm = wch;
- if (bArabicNumber) {
- wForm += 0x0630;
- }
- } else if (wch == L'.') {
- wForm = wch;
- if (bArabicNumber) {
- wNext = 0xFEFF;
- if (pAccess != NULL) {
- iNext = i + 1;
- if (iNext <= iLength) {
- wNext = pAccess->GetChar(pIdentity, iNext);
- }
- } else {
- if (i < iLength) {
- wNext = *pStr;
- }
- }
- if (wNext >= L'0' && wNext <= L'9') {
- wForm = 0x066B;
- }
- }
- } else if (wch == L',') {
- wForm = wch;
- if (bArabicComma) {
- wForm = 0x060C;
- }
- } else if (bRTLPiece || bVerticalChar) {
- wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
- } else {
- wForm = wch;
- }
- if (dwCharType != FX_CHARTYPE_Combination) {
- bShadda = FALSE;
- }
- if (dwCharType < FX_CHARTYPE_ArabicAlef) {
- bLam = FALSE;
- }
- dwProps = FX_GetUnicodeProperties(wForm);
- iCharRotation = iRotation;
- if (bVerticalChar && (dwProps & 0x8000) != 0) {
- iCharRotation++;
- }
- iCharRotation %= 4;
- bEmptyChar =
- (dwCharType >= FX_CHARTYPE_Tab && dwCharType <= FX_CHARTYPE_Control);
- if (wForm == 0xFEFF) {
- bEmptyChar = TRUE;
- }
- iForms = bLam ? 3 : 1;
- iCount += (bEmptyChar && bSkipSpace) ? 0 : iForms;
- if (pCharPos == NULL) {
- if (iWidth > 0) {
- wPrev = wch;
- }
- wLast = wch;
- continue;
- }
- iCharWidth = iWidth;
- if (iCharWidth < 0) {
- iCharWidth = -iCharWidth;
- }
- iCharWidth /= iFontSize;
- formChars[0].wch = wch;
- formChars[0].wForm = wForm;
- formChars[0].iWidth = iCharWidth;
- if (bLam) {
- formChars[1].wForm = 0x0651;
- iCharWidth = 0;
- pFont->GetCharWidth(0x0651, iCharWidth, FALSE);
- formChars[1].iWidth = iCharWidth;
- formChars[2].wForm = 0x0670;
- iCharWidth = 0;
- pFont->GetCharWidth(0x0670, iCharWidth, FALSE);
- formChars[2].iWidth = iCharWidth;
- }
- for (int32_t j = 0; j < iForms; j++) {
- wForm = (FX_WCHAR)formChars[j].wForm;
- iCharWidth = formChars[j].iWidth;
- if (j > 0) {
- dwCharType = FX_CHARTYPE_Combination;
- wch = wForm;
- wLast = (FX_WCHAR)formChars[j - 1].wForm;
- }
- if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
- pCharPos->m_GlyphIndex =
- bCharCode ? wch : pFont->GetGlyphIndex(wForm, FALSE);
- pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
- pCharPos->m_FontCharWidth = iCharWidth;
- if (pWSForms) {
- *pWSForms += wForm;
- }
- }
- if (bVerticalDoc) {
- iCharHeight = iCharWidth;
- iCharWidth = 1000;
- } else {
- iCharHeight = 1000;
- }
- fCharWidth = fFontSize * iCharWidth / 1000.0f;
- fCharHeight = fFontSize * iCharHeight / 1000.0f;
- if (bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
- if (bVerticalDoc) {
- fY -= fCharHeight;
- } else {
- fX -= fCharWidth;
- }
- }
- if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
- pCharPos->m_OriginX = fX;
- pCharPos->m_OriginY = fY;
- if ((dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0) {
- int32_t iFormWidth = iCharWidth;
- pFont->GetCharWidth(wForm, iFormWidth, FALSE);
- FX_FLOAT fOffset = fFontSize * (iCharWidth - iFormWidth) / 2000.0f;
- if (bVerticalDoc) {
- pCharPos->m_OriginY += fOffset;
- } else {
- pCharPos->m_OriginX += fOffset;
- }
- }
- if (dwCharType == FX_CHARTYPE_Combination) {
- CFX_Rect rtBBox;
- rtBBox.Reset();
- if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
- pCharPos->m_OriginY =
- fYBase + fFontSize -
- fFontSize * (FX_FLOAT)rtBBox.height / (FX_FLOAT)iMaxHeight;
- }
- if (wForm == wch && wLast != 0xFEFF) {
- FX_DWORD dwLastProps = FX_GetUnicodeProperties(wLast);
- if ((dwLastProps & FX_CHARTYPEBITSMASK) ==
- FX_CHARTYPE_Combination) {
- CFX_Rect rtBBox;
- rtBBox.Reset();
- if (pFont->GetCharBBox(wLast, rtBBox, FALSE)) {
- pCharPos->m_OriginY -= fFontSize * rtBBox.height / iMaxHeight;
- }
- }
- }
- }
- CFX_PointF ptOffset;
- ptOffset.Reset();
- FX_BOOL bAdjusted = FALSE;
- if (pAdjustPos) {
- bAdjusted = pAdjustPos(wForm, bCharCode, pFont, fFontSize,
- bVerticalChar, ptOffset);
- }
- if (!bAdjusted && bVerticalChar && (dwProps & 0x00010000) != 0) {
- CFX_Rect rtBBox;
- rtBBox.Reset();
- if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
- ptOffset.x = fFontSize * (850 - rtBBox.right()) / iMaxHeight;
- ptOffset.y = fFontSize * (iAscent - rtBBox.top - 150) / iMaxHeight;
- }
- }
- pCharPos->m_OriginX += ptOffset.x;
- pCharPos->m_OriginY -= ptOffset.y;
- }
- if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
- if (bVerticalDoc) {
- fY += fCharHeight;
- } else {
- fX += fCharWidth;
- }
- }
- if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
- pCharPos->m_bGlyphAdjust = TRUE;
- if (bVerticalDoc) {
- if (iCharRotation == 0) {
- pCharPos->m_AdjustMatrix[0] = -1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = 1;
- pCharPos->m_OriginY += fAscent;
- } else if (iCharRotation == 1) {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = -1;
- pCharPos->m_AdjustMatrix[2] = -1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX -= fDescent;
- } else if (iCharRotation == 2) {
- pCharPos->m_AdjustMatrix[0] = 1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = -1;
- pCharPos->m_OriginX += fCharWidth;
- pCharPos->m_OriginY += fAscent;
- } else {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = 1;
- pCharPos->m_AdjustMatrix[2] = 1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX += fAscent;
- }
- } else {
- if (iCharRotation == 0) {
- pCharPos->m_AdjustMatrix[0] = -1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = 1;
- } else if (iCharRotation == 1) {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = -1;
- pCharPos->m_AdjustMatrix[2] = -1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX -= fDescent;
- pCharPos->m_OriginY -= fAscent + fDescent;
- } else if (iCharRotation == 2) {
- pCharPos->m_AdjustMatrix[0] = 1;
- pCharPos->m_AdjustMatrix[1] = 0;
- pCharPos->m_AdjustMatrix[2] = 0;
- pCharPos->m_AdjustMatrix[3] = -1;
- pCharPos->m_OriginX += fCharWidth;
- pCharPos->m_OriginY -= fAscent;
- } else {
- pCharPos->m_AdjustMatrix[0] = 0;
- pCharPos->m_AdjustMatrix[1] = 1;
- pCharPos->m_AdjustMatrix[2] = 1;
- pCharPos->m_AdjustMatrix[3] = 0;
- pCharPos->m_OriginX += 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 (iWidth > 0) {
- wPrev = (FX_WCHAR)formChars[0].wch;
- }
- wLast = wch;
- }
- return iCount;
-}
-int32_t CFX_TxtBreak::GetCharRects(FX_LPCTXTRUN pTxtRun,
- CFX_RectFArray& rtArray,
- FX_BOOL bCharBBox) const {
- if (pTxtRun == NULL || pTxtRun->iLength < 1) {
- return 0;
- }
- IFX_TxtAccess* pAccess = pTxtRun->pAccess;
- void* pIdentity = pTxtRun->pIdentity;
- const FX_WCHAR* pStr = pTxtRun->pStr;
- int32_t* pWidths = pTxtRun->pWidths;
- int32_t iLength = pTxtRun->iLength;
- CFX_RectF rect(*pTxtRun->pRect);
- FX_BOOL bRTLPiece =
- (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
- FX_FLOAT fFontSize = pTxtRun->fFontSize;
- int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
- FX_FLOAT fScale = fFontSize / 1000.0f;
- IFX_Font* pFont = pTxtRun->pFont;
- if (pFont == NULL) {
- bCharBBox = FALSE;
- }
- CFX_Rect bbox;
- bbox.Set(0, 0, 0, 0);
- if (bCharBBox) {
- bCharBBox = pFont->GetBBox(bbox);
- }
- FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
- FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
- rtArray.RemoveAll();
- rtArray.SetSize(iLength);
- FX_BOOL bVertical =
- (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
- FX_BOOL bSingleLine = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
- FX_BOOL bCombText = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
- FX_WCHAR wch, wLineBreakChar = pTxtRun->wLineBreakChar;
- int32_t iCharSize;
- FX_FLOAT fCharSize, fStart;
- if (bVertical) {
- fStart = bRTLPiece ? rect.bottom() : rect.top;
- } else {
- fStart = bRTLPiece ? rect.right() : rect.left;
- }
- for (int32_t i = 0; i < iLength; i++) {
- if (pAccess != NULL) {
- wch = pAccess->GetChar(pIdentity, i);
- iCharSize = pAccess->GetWidth(pIdentity, i);
- } else {
- wch = *pStr++;
- iCharSize = *pWidths++;
- }
- fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
- FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
- if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 ||
- (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
- bRet = FALSE;
- }
- if (bRet) {
- iCharSize = iFontSize * 500;
- fCharSize = fFontSize / 2.0f;
- }
- if (bVertical) {
- rect.top = fStart;
- if (bRTLPiece) {
- rect.top -= fCharSize;
- fStart -= fCharSize;
- } else {
- fStart += fCharSize;
- }
- rect.height = fCharSize;
- } else {
- rect.left = fStart;
- if (bRTLPiece) {
- rect.left -= fCharSize;
- fStart -= fCharSize;
- } else {
- fStart += fCharSize;
- }
- rect.width = fCharSize;
- }
- if (bCharBBox && !bRet) {
- int32_t iCharWidth = 1000;
- pFont->GetCharWidth(wch, iCharWidth);
- FX_FLOAT fRTLeft = 0, fCharWidth = 0;
- if (iCharWidth > 0) {
- fCharWidth = iCharWidth * fScale;
- fRTLeft = fLeft;
- if (bCombText) {
- fRTLeft = (rect.width - fCharWidth) / 2.0f;
- }
- }
- CFX_RectF rtBBoxF;
- if (bVertical) {
- rtBBoxF.top = rect.left + fRTLeft;
- rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
- rtBBoxF.height = fCharWidth;
- rtBBoxF.width = fHeight;
- rtBBoxF.left = std::max(rtBBoxF.left, 0.0f);
- } else {
- rtBBoxF.left = rect.left + fRTLeft;
- rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
- rtBBoxF.width = fCharWidth;
- rtBBoxF.height = fHeight;
- rtBBoxF.top = std::max(rtBBoxF.top, 0.0f);
- }
- rtArray.SetAt(i, rtBBoxF);
- continue;
- }
- rtArray.SetAt(i, rect);
- }
- return iLength;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "core/include/fxcrt/fx_arb.h"
+#include "xfa/src/fgas/include/fx_lbk.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "xfa/src/fgas/src/layout/fx_unicode.h"
+#include "xfa/src/fgas/src/layout/fx_textbreak.h"
+
+extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32];
+IFX_TxtBreak* IFX_TxtBreak::Create(FX_DWORD dwPolicies) {
+ return new CFX_TxtBreak(dwPolicies);
+}
+CFX_TxtBreak::CFX_TxtBreak(FX_DWORD dwPolicies)
+ : m_dwPolicies(dwPolicies),
+ m_pArabicChar(NULL),
+ m_iLineWidth(2000000),
+ m_dwLayoutStyles(0),
+ m_bVertical(FALSE),
+ m_bArabicContext(FALSE),
+ m_bArabicShapes(FALSE),
+ m_bRTL(FALSE),
+ m_bSingleLine(FALSE),
+ m_bCombText(FALSE),
+ m_iArabicContext(1),
+ m_iCurArabicContext(1),
+ m_pFont(NULL),
+ m_iFontSize(240),
+ m_bEquidistant(TRUE),
+ m_iTabWidth(720000),
+ m_wDefChar(0xFEFF),
+ m_wParagBreakChar(L'\n'),
+ m_iDefChar(0),
+ m_iLineRotation(0),
+ m_iCharRotation(0),
+ m_iRotation(0),
+ m_iAlignment(FX_TXTLINEALIGNMENT_Left),
+ m_dwContextCharStyles(0),
+ m_iCombWidth(360000),
+ m_pUserData(NULL),
+ m_dwCharType(0),
+ m_bArabicNumber(FALSE),
+ m_bArabicComma(FALSE),
+ m_pCurLine(NULL),
+ m_iReady(0),
+ m_iTolerance(0),
+ m_iHorScale(100),
+ m_iVerScale(100),
+ m_iCharSpace(0) {
+ m_bPagination = (m_dwPolicies & FX_TXTBREAKPOLICY_Pagination) != 0;
+ m_pArabicChar = IFX_ArabicChar::Create();
+ if (m_bPagination) {
+ m_pTxtLine1 = new CFX_TxtLine(sizeof(CFX_Char));
+ m_pTxtLine2 = new CFX_TxtLine(sizeof(CFX_Char));
+ } else {
+ m_pTxtLine1 = new CFX_TxtLine(sizeof(CFX_TxtChar));
+ m_pTxtLine2 = new CFX_TxtLine(sizeof(CFX_TxtChar));
+ }
+ m_pCurLine = m_pTxtLine1;
+ ResetArabicContext();
+}
+CFX_TxtBreak::~CFX_TxtBreak() {
+ Reset();
+ delete m_pTxtLine1;
+ delete m_pTxtLine2;
+ m_pArabicChar->Release();
+}
+void CFX_TxtBreak::SetLineWidth(FX_FLOAT fLineWidth) {
+ m_iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
+ FXSYS_assert(m_iLineWidth >= 20000);
+}
+void CFX_TxtBreak::SetLinePos(FX_FLOAT fLinePos) {
+ int32_t iLinePos = FXSYS_round(fLinePos * 20000.0f);
+ if (iLinePos < 0) {
+ iLinePos = 0;
+ }
+ if (iLinePos > m_iLineWidth) {
+ iLinePos = m_iLineWidth;
+ }
+ m_pCurLine->m_iStart = iLinePos;
+ m_pCurLine->m_iWidth += iLinePos;
+}
+void CFX_TxtBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles) {
+ m_dwLayoutStyles = dwLayoutStyles;
+ m_bVertical = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
+ m_bArabicContext = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicContext) != 0;
+ m_bArabicShapes = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicShapes) != 0;
+ m_bRTL = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_RTLReadingOrder) != 0;
+ m_bSingleLine = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
+ m_bCombText = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ ResetArabicContext();
+ m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_TxtBreak::SetFont(IFX_Font* pFont) {
+ if (pFont == NULL) {
+ return;
+ }
+ if (m_pFont == pFont) {
+ return;
+ }
+ SetBreakStatus();
+ m_pFont = pFont;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+}
+void CFX_TxtBreak::SetFontSize(FX_FLOAT fFontSize) {
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ if (m_iFontSize == iFontSize) {
+ return;
+ }
+ SetBreakStatus();
+ m_iFontSize = iFontSize;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+}
+void CFX_TxtBreak::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
+ m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
+ if (m_iTabWidth < FX_TXTBREAK_MinimumTabWidth) {
+ m_iTabWidth = FX_TXTBREAK_MinimumTabWidth;
+ }
+ m_bEquidistant = bEquidistant;
+}
+void CFX_TxtBreak::SetDefaultChar(FX_WCHAR wch) {
+ m_wDefChar = wch;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ if (m_iDefChar < 0) {
+ m_iDefChar = 0;
+ } else {
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_TxtBreak::SetParagraphBreakChar(FX_WCHAR wch) {
+ if (wch != L'\r' && wch != L'\n') {
+ return;
+ }
+ m_wParagBreakChar = wch;
+}
+void CFX_TxtBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) {
+ m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
+}
+void CFX_TxtBreak::SetCharRotation(int32_t iCharRotation) {
+ if (iCharRotation < 0) {
+ iCharRotation += (-iCharRotation / 4 + 1) * 4;
+ } else if (iCharRotation > 3) {
+ iCharRotation -= (iCharRotation / 4) * 4;
+ }
+ if (m_iCharRotation == iCharRotation) {
+ return;
+ }
+ SetBreakStatus();
+ m_iCharRotation = iCharRotation;
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_TxtBreak::SetAlignment(int32_t iAlignment) {
+ FXSYS_assert(iAlignment >= FX_TXTLINEALIGNMENT_Left &&
+ iAlignment <= FX_TXTLINEALIGNMENT_Distributed);
+ m_iAlignment = iAlignment;
+ ResetArabicContext();
+}
+void CFX_TxtBreak::ResetContextCharStyles() {
+ m_dwContextCharStyles = m_bArabicContext ? m_iCurAlignment : m_iAlignment;
+ if (m_bArabicNumber) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicNumber;
+ }
+ if (m_bArabicComma) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
+ }
+ if ((m_bArabicContext && m_bCurRTL) || (!m_bArabicContext && m_bRTL)) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_RTLReadingOrder;
+ }
+ m_dwContextCharStyles |= (m_iArabicContext << 8);
+}
+FX_DWORD CFX_TxtBreak::GetContextCharStyles() const {
+ return m_dwContextCharStyles;
+}
+void CFX_TxtBreak::SetContextCharStyles(FX_DWORD dwCharStyles) {
+ m_iCurAlignment = dwCharStyles & 0x0F;
+ m_bArabicNumber = (dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
+ m_bArabicComma = (dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
+ m_bCurRTL = (dwCharStyles & FX_TXTCHARSTYLE_RTLReadingOrder) != 0;
+ m_iCurArabicContext = m_iArabicContext = ((dwCharStyles & 0x0300) >> 8);
+ ResetContextCharStyles();
+}
+void CFX_TxtBreak::SetCombWidth(FX_FLOAT fCombWidth) {
+ m_iCombWidth = FXSYS_round(fCombWidth * 20000.0f);
+}
+void CFX_TxtBreak::SetUserData(void* pUserData) {
+ if (m_pUserData == pUserData) {
+ return;
+ }
+ SetBreakStatus();
+ m_pUserData = pUserData;
+}
+void CFX_TxtBreak::SetBreakStatus() {
+ if (m_bPagination) {
+ return;
+ }
+ int32_t iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return;
+ }
+ CFX_TxtChar* pTC = (CFX_TxtChar*)m_pCurLine->GetCharPtr(iCount - 1);
+ if (pTC->m_dwStatus == 0) {
+ pTC->m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+}
+void CFX_TxtBreak::SetHorizontalScale(int32_t iScale) {
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (iScale == m_iHorScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iHorScale = iScale;
+}
+void CFX_TxtBreak::SetVerticalScale(int32_t iScale) {
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (iScale == m_iHorScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iVerScale = iScale;
+}
+void CFX_TxtBreak::SetCharSpace(FX_FLOAT fCharSpace) {
+ m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
+}
+static const int32_t gs_FX_TxtLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
+int32_t CFX_TxtBreak::GetLineRotation(FX_DWORD dwStyles) const {
+ return gs_FX_TxtLineRotations[(dwStyles & 0x0E) >> 1];
+}
+CFX_TxtChar* CFX_TxtBreak::GetLastChar(int32_t index, FX_BOOL bOmitChar) const {
+ CFX_TxtCharArray& ca = *m_pCurLine->m_pLineChars;
+ int32_t iCount = ca.GetSize();
+ if (index < 0 || index >= iCount) {
+ return NULL;
+ }
+ CFX_TxtChar* pTC;
+ int32_t iStart = iCount - 1;
+ while (iStart > -1) {
+ pTC = ca.GetDataPtr(iStart--);
+ if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) {
+ continue;
+ }
+ if (--index < 0) {
+ return pTC;
+ }
+ }
+ return NULL;
+}
+CFX_TxtLine* CFX_TxtBreak::GetTxtLine(FX_BOOL bReady) const {
+ if (!bReady) {
+ return m_pCurLine;
+ }
+ if (m_iReady == 1) {
+ return m_pTxtLine1;
+ } else if (m_iReady == 2) {
+ return m_pTxtLine2;
+ } else {
+ return NULL;
+ }
+}
+CFX_TxtPieceArray* CFX_TxtBreak::GetTxtPieces(FX_BOOL bReady) const {
+ CFX_TxtLine* pTxtLine = GetTxtLine(bReady);
+ if (pTxtLine == NULL) {
+ return NULL;
+ }
+ return pTxtLine->m_pLinePieces;
+}
+inline FX_DWORD CFX_TxtBreak::GetUnifiedCharType(FX_DWORD dwType) const {
+ return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
+}
+void CFX_TxtBreak::ResetArabicContext() {
+ if (m_bArabicContext) {
+ m_bCurRTL = m_iCurArabicContext > 1;
+ m_iCurAlignment = m_iCurArabicContext > 1 ? FX_TXTLINEALIGNMENT_Right
+ : FX_TXTLINEALIGNMENT_Left;
+ m_iCurAlignment |= (m_iAlignment & FX_TXTLINEALIGNMENT_HigherMask);
+ m_bArabicNumber = m_iArabicContext >= 1 && m_bArabicShapes;
+ } else {
+ if (m_bPagination) {
+ m_bCurRTL = FALSE;
+ m_iCurAlignment = 0;
+ } else {
+ m_bCurRTL = m_bRTL;
+ m_iCurAlignment = m_iAlignment;
+ }
+ if (m_bRTL) {
+ m_bArabicNumber = m_iArabicContext >= 1;
+ } else {
+ m_bArabicNumber = m_iArabicContext > 1;
+ }
+ m_bArabicNumber = m_bArabicNumber && m_bArabicShapes;
+ }
+ m_bArabicComma = m_bArabicNumber;
+ ResetContextCharStyles();
+}
+void CFX_TxtBreak::AppendChar_PageLoad(CFX_Char* pCurChar, FX_DWORD dwProps) {
+ if (!m_bPagination) {
+ ((CFX_TxtChar*)pCurChar)->m_dwStatus = 0;
+ ((CFX_TxtChar*)pCurChar)->m_pUserData = m_pUserData;
+ }
+ if (m_bArabicContext || m_bArabicShapes) {
+ int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
+ int32_t iArabicContext =
+ (iBidiCls == FX_BIDICLASS_R || iBidiCls == FX_BIDICLASS_AL)
+ ? 2
+ : ((iBidiCls == FX_BIDICLASS_L || iBidiCls == FX_BIDICLASS_S) ? 0
+ : 1);
+ if (iArabicContext != m_iArabicContext && iArabicContext != 1) {
+ m_iArabicContext = iArabicContext;
+ if (m_iCurArabicContext == 1) {
+ m_iCurArabicContext = iArabicContext;
+ }
+ ResetArabicContext();
+ if (!m_bPagination) {
+ CFX_TxtChar* pLastChar = (CFX_TxtChar*)GetLastChar(1, FALSE);
+ if (pLastChar != NULL && pLastChar->m_dwStatus < 1) {
+ pLastChar->m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+ }
+ }
+ }
+ pCurChar->m_dwCharStyles = m_dwContextCharStyles;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Combination(CFX_Char* pCurChar,
+ int32_t iRotation) {
+ FXSYS_assert(pCurChar != NULL);
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ FX_WCHAR wForm;
+ int32_t iCharWidth = 0;
+ CFX_Char* pLastChar;
+ pCurChar->m_iCharWidth = -1;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ wForm = wch;
+ if (!m_bPagination) {
+ pLastChar = GetLastChar(0, FALSE);
+ if (pLastChar != NULL &&
+ (((CFX_TxtChar*)pLastChar)->m_dwCharStyles &
+ FX_TXTCHARSTYLE_ArabicShadda) == 0) {
+ FX_BOOL bShadda = FALSE;
+ if (wch == 0x0651) {
+ FX_WCHAR wLast = pLastChar->m_wCharCode;
+ if (wLast >= 0x064C && wLast <= 0x0650) {
+ wForm = FX_GetArabicFromShaddaTable(wLast);
+ bShadda = TRUE;
+ }
+ } else if (wch >= 0x064C && wch <= 0x0650) {
+ if (pLastChar->m_wCharCode == 0x0651) {
+ wForm = FX_GetArabicFromShaddaTable(wch);
+ bShadda = TRUE;
+ }
+ }
+ if (bShadda) {
+ ((CFX_TxtChar*)pLastChar)->m_dwCharStyles |=
+ FX_TXTCHARSTYLE_ArabicShadda;
+ ((CFX_TxtChar*)pLastChar)->m_iCharWidth = 0;
+ ((CFX_TxtChar*)pCurChar)->m_dwCharStyles |=
+ FX_TXTCHARSTYLE_ArabicShadda;
+ }
+ }
+ }
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = 0;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCurChar->m_iCharWidth = -iCharWidth;
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Tab(CFX_Char* pCurChar, int32_t iRotation) {
+ m_dwCharType = FX_CHARTYPE_Tab;
+ if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) {
+ return FX_TXTBREAK_None;
+ }
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ int32_t iCharWidth;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bEquidistant) {
+ iCharWidth = iLineWidth;
+ iCharWidth = m_iTabWidth * (iCharWidth / m_iTabWidth + 1) - iCharWidth;
+ if (iCharWidth < FX_TXTBREAK_MinimumTabWidth) {
+ iCharWidth += m_iTabWidth;
+ }
+ } else {
+ iCharWidth = m_iTabWidth;
+ }
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ if (!m_bSingleLine && iLineWidth >= m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Control(CFX_Char* pCurChar,
+ int32_t iRotation) {
+ m_dwCharType = FX_CHARTYPE_Control;
+ FX_DWORD dwRet = FX_TXTBREAK_None;
+ if (!m_bSingleLine) {
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ switch (wch) {
+ case L'\v':
+ case 0x2028:
+ dwRet = FX_TXTBREAK_LineBreak;
+ break;
+ case L'\f':
+ dwRet = FX_TXTBREAK_PageBreak;
+ break;
+ case 0x2029:
+ dwRet = FX_TXTBREAK_ParagraphBreak;
+ break;
+ default:
+ if (wch == m_wParagBreakChar) {
+ dwRet = FX_TXTBREAK_ParagraphBreak;
+ }
+ break;
+ }
+ if (dwRet != FX_TXTBREAK_None) {
+ dwRet = EndBreak(dwRet);
+ }
+ }
+ return dwRet;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Arabic(CFX_Char* pCurChar,
+ int32_t iRotation) {
+ FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ FX_WCHAR wForm;
+ int32_t iCharWidth = 0;
+ CFX_Char* pLastChar = NULL;
+ FX_BOOL bAlef = FALSE;
+ if (!m_bCombText && m_dwCharType >= FX_CHARTYPE_ArabicAlef &&
+ m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
+ pLastChar = GetLastChar(1);
+ if (pLastChar != NULL) {
+ iCharWidth = pLastChar->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iLineWidth -= iCharWidth;
+ }
+ CFX_Char* pPrevChar = GetLastChar(2);
+ wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
+ bAlef = (wForm == 0xFEFF &&
+ pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
+ int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
+ if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
+ iLastRotation++;
+ }
+ if (m_bVertical != FX_IsOdd(iLastRotation)) {
+ iCharWidth = 1000;
+ } else {
+ m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
+ }
+ if (wForm == 0xFEFF) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ pLastChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ iCharWidth = 0;
+ }
+ }
+ m_dwCharType = dwType;
+ wForm = m_pArabicChar->GetFormChar(pCurChar, bAlef ? NULL : pLastChar, NULL);
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
+ }
+ if (wForm == 0xFEFF) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ m_pCurLine->m_iArabicChars++;
+ if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Others(CFX_Char* pCurChar,
+ int32_t iRotation) {
+ FX_DWORD dwProps = pCurChar->m_dwCharProps;
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ int32_t iCharWidth = 0;
+ m_dwCharType = dwType;
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ FX_WCHAR wForm = wch;
+ if (dwType == FX_CHARTYPE_Numeric) {
+ if (m_bArabicNumber) {
+ wForm = wch + 0x0630;
+ pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicIndic;
+ }
+ } else if (wch == L',') {
+ if (m_bArabicShapes && m_iCurArabicContext > 0) {
+ wForm = 0x060C;
+ pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
+ }
+ } else if (m_bCurRTL || m_bVertical) {
+ wForm = FX_GetMirrorChar(wch, dwProps, m_bCurRTL, m_bVertical);
+ }
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ iCharWidth += m_iCharSpace;
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space ||
+ (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0);
+ if (!m_bSingleLine && bBreak && iLineWidth > m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+typedef FX_DWORD (CFX_TxtBreak::*FX_TxtBreak_LPFAppendChar)(CFX_Char* pCurChar,
+ int32_t iRotation);
+static const FX_TxtBreak_LPFAppendChar g_FX_TxtBreak_lpfAppendChar[16] = {
+ &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Tab,
+ &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Control,
+ &CFX_TxtBreak::AppendChar_Combination, &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic, &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Others, &CFX_TxtBreak::AppendChar_Others,
+};
+FX_DWORD CFX_TxtBreak::AppendChar(FX_WCHAR wch) {
+ FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ CFX_TxtChar* pCurChar = m_pCurLine->m_pLineChars->AddSpace();
+ pCurChar->m_wCharCode = (FX_WORD)wch;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_dwCharProps = dwProps;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_iHorizontalScale = m_iHorScale;
+ pCurChar->m_iVertialScale = m_iVerScale;
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_iBidiClass = 0;
+ pCurChar->m_iBidiLevel = 0;
+ pCurChar->m_iBidiPos = 0;
+ pCurChar->m_iBidiOrder = 0;
+ pCurChar->m_pUserData = NULL;
+ AppendChar_PageLoad(pCurChar, dwProps);
+ FX_DWORD dwRet1 = FX_TXTBREAK_None;
+ if (dwType != FX_CHARTYPE_Combination &&
+ GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
+ if (m_dwCharType > 0 &&
+ m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine) {
+ if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
+ dwRet1 = EndBreak(FX_TXTBREAK_LineBreak);
+ int32_t iCount = m_pCurLine->CountChars();
+ if (iCount > 0) {
+ pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1);
+ }
+ }
+ }
+ }
+ int32_t iRotation = m_iRotation;
+ if (m_bVertical && (dwProps & 0x8000) != 0) {
+ iRotation = (iRotation + 1) % 4;
+ }
+ FX_DWORD dwRet2 =
+ (this->*g_FX_TxtBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(
+ pCurChar, iRotation);
+ return std::max(dwRet1, dwRet2);
+}
+void CFX_TxtBreak::EndBreak_UpdateArabicShapes() {
+ FXSYS_assert(m_bArabicShapes);
+ int32_t iCount = m_pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ int32_t& iLineWidth = m_pCurLine->m_iWidth;
+ CFX_Char *pCur, *pNext;
+ pCur = m_pCurLine->GetCharPtr(0);
+ FX_BOOL bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ pCur = m_pCurLine->GetCharPtr(1);
+ FX_WCHAR wch, wForm;
+ FX_BOOL bNextNum;
+ int32_t i = 1, iCharWidth, iRotation;
+ do {
+ i++;
+ if (i < iCount) {
+ pNext = m_pCurLine->GetCharPtr(i);
+ bNextNum = (pNext->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ } else {
+ pNext = NULL;
+ bNextNum = FALSE;
+ }
+ wch = pCur->m_wCharCode;
+ if (wch == L'.') {
+ if (bPrevNum && bNextNum) {
+ iRotation = m_iRotation;
+ if (m_bVertical && (pCur->m_dwCharProps & 0x8000) != 0) {
+ iRotation = ((iRotation + 1) & 0x03);
+ }
+ wForm = wch == L'.' ? 0x066B : 0x066C;
+ iLineWidth -= pCur->m_iCharWidth;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCur->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ }
+ }
+ bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ pCur = pNext;
+ } while (i < iCount);
+}
+FX_BOOL CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus) {
+ int32_t iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = FALSE;
+ CFX_Char* pTC;
+ if (!m_bSingleLine && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance) {
+ pTC = m_pCurLine->GetCharPtr(iCount - 1);
+ switch (pTC->GetCharType()) {
+ case FX_CHARTYPE_Tab:
+ case FX_CHARTYPE_Control:
+ break;
+ case FX_CHARTYPE_Space:
+ if ((m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ default:
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ break;
+ }
+ }
+ iCount = m_pCurLine->CountChars();
+ CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
+ CFX_TxtPiece tp;
+ if (m_bPagination) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_iWidth = m_pCurLine->m_iWidth;
+ tp.m_iStartChar = 0;
+ tp.m_iChars = iCount;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ tp.m_pUserData = m_pUserData;
+ pTC = m_pCurLine->GetCharPtr(0);
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ pCurPieces->Add(tp);
+ m_pCurLine = pNextLine;
+ m_dwCharType = 0;
+ return TRUE;
+ }
+ if (bAllChars && !bDone) {
+ int32_t iEndPos = m_pCurLine->m_iWidth;
+ GetBreakPos(*m_pCurLine->m_pLineChars, iEndPos, bAllChars, TRUE);
+ }
+ return FALSE;
+}
+void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus) {
+ CFX_TxtPiece tp;
+ FX_TPO tpo;
+ CFX_TxtChar* pTC;
+ int32_t i, j;
+ CFX_TxtCharArray& chars = *m_pCurLine->m_pLineChars;
+ int32_t iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL);
+ if (!m_bPagination && bDone) {
+ int32_t iBidiNum = 0;
+ for (i = 0; i < iCount; i++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiPos = i;
+ if (pTC->GetCharType() != FX_CHARTYPE_Control) {
+ iBidiNum = i;
+ }
+ if (i == 0) {
+ pTC->m_iBidiLevel = 1;
+ }
+ }
+ FX_BidiLine(chars, iBidiNum + 1, m_bCurRTL ? 1 : 0);
+ }
+ CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
+ if (!m_bPagination &&
+ (bDone || (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_MutipleFormat) != 0)) {
+ tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ int32_t iBidiLevel = -1, iCharWidth;
+ i = 0, j = -1;
+ while (i < iCount) {
+ pTC = chars.GetDataPtr(i);
+ if (iBidiLevel < 0) {
+ iBidiLevel = pTC->m_iBidiLevel;
+ tp.m_iWidth = 0;
+ tp.m_iBidiLevel = iBidiLevel;
+ tp.m_iBidiPos = pTC->m_iBidiOrder;
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_pUserData = pTC->m_pUserData;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+ if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwStatus != 0) {
+ if (iBidiLevel == pTC->m_iBidiLevel) {
+ tp.m_dwStatus = pTC->m_dwStatus;
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i++;
+ }
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iStartChar = i;
+ tpo.index = ++j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ iBidiLevel = -1;
+ } else {
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i++;
+ }
+ }
+ if (i > tp.m_iStartChar) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tpo.index = ++j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ }
+ if (j > -1) {
+ if (j > 0) {
+ FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
+ int32_t iStartPos = 0;
+ for (i = 0; i <= j; i++) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
+ ttp.m_iStartPos = iStartPos;
+ iStartPos += ttp.m_iWidth;
+ }
+ }
+ CFX_TxtPiece& ttp = pCurPieces->GetAt(j);
+ ttp.m_dwStatus = dwStatus;
+ }
+ } else {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_iWidth = m_pCurLine->m_iWidth;
+ tp.m_iStartChar = 0;
+ tp.m_iChars = iCount;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ tp.m_pUserData = m_pUserData;
+ pTC = chars.GetDataPtr(0);
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ pCurPieces->Add(tp);
+ tpo.index = 0;
+ tpo.pos = 0;
+ tpos.Add(tpo);
+ }
+}
+void CFX_TxtBreak::EndBreak_Alignment(CFX_TPOArray& tpos,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus) {
+ int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
+ CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
+ int32_t i, j, iCount = pCurPieces->GetSize();
+ FX_BOOL bFind = FALSE;
+ FX_TPO tpo;
+ CFX_TxtChar* pTC;
+ FX_DWORD dwCharType;
+ for (i = iCount - 1; i > -1; i--) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
+ if (!bFind) {
+ iNetWidth = ttp.GetEndPos();
+ }
+ FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
+ j = bArabic ? 0 : ttp.m_iChars - 1;
+ while (j > -1 && j < ttp.m_iChars) {
+ pTC = ttp.GetCharPtr(j);
+ if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK) {
+ iGapChars++;
+ }
+ if (!bFind || !bAllChars) {
+ dwCharType = pTC->GetCharType();
+ if (dwCharType == FX_CHARTYPE_Space ||
+ dwCharType == FX_CHARTYPE_Control) {
+ if (!bFind) {
+ iCharWidth = pTC->m_iCharWidth;
+ if (bAllChars && iCharWidth > 0) {
+ iNetWidth -= iCharWidth;
+ }
+ }
+ } else {
+ bFind = TRUE;
+ if (!bAllChars) {
+ break;
+ }
+ }
+ }
+ j += bArabic ? 1 : -1;
+ }
+ if (!bAllChars && bFind) {
+ break;
+ }
+ }
+ int32_t iOffset = m_iLineWidth - iNetWidth;
+ int32_t iLowerAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_LowerMask);
+ int32_t iHigherAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_HigherMask);
+ if (iGapChars > 0 && (iHigherAlignment == FX_TXTLINEALIGNMENT_Distributed ||
+ (iHigherAlignment == FX_TXTLINEALIGNMENT_Justified &&
+ dwStatus != FX_TXTBREAK_ParagraphBreak))) {
+ int32_t iStart = -1;
+ for (i = 0; i < iCount; i++) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index);
+ if (iStart < -1) {
+ iStart = ttp.m_iStartPos;
+ } else {
+ ttp.m_iStartPos = iStart;
+ }
+ int32_t k;
+ for (j = 0; j < ttp.m_iChars; j++) {
+ pTC = ttp.GetCharPtr(j);
+ if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0) {
+ continue;
+ }
+ k = iOffset / iGapChars;
+ pTC->m_iCharWidth += k;
+ ttp.m_iWidth += k;
+ iOffset -= k;
+ iGapChars--;
+ if (iGapChars < 1) {
+ break;
+ }
+ }
+ iStart += ttp.m_iWidth;
+ }
+ } else if (iLowerAlignment > FX_TXTLINEALIGNMENT_Left) {
+ if (iLowerAlignment == FX_TXTLINEALIGNMENT_Center) {
+ iOffset /= 2;
+ }
+ if (iOffset > 0) {
+ for (i = 0; i < iCount; i++) {
+ CFX_TxtPiece& ttp = pCurPieces->GetAt(i);
+ ttp.m_iStartPos += iOffset;
+ }
+ }
+ }
+}
+FX_DWORD CFX_TxtBreak::EndBreak(FX_DWORD dwStatus) {
+ FXSYS_assert(dwStatus >= FX_TXTBREAK_PieceBreak &&
+ dwStatus <= FX_TXTBREAK_PageBreak);
+ CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces;
+ int32_t iCount = pCurPieces->GetSize();
+ if (iCount > 0) {
+ CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount);
+ if (dwStatus > FX_TXTBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ } else {
+ CFX_TxtLine* pLastLine = GetTxtLine(TRUE);
+ if (pLastLine != NULL) {
+ pCurPieces = pLastLine->m_pLinePieces;
+ iCount = pCurPieces->GetSize();
+ if (iCount-- > 0) {
+ CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(iCount);
+ if (dwStatus > FX_TXTBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ }
+ return FX_TXTBREAK_None;
+ }
+ iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return FX_TXTBREAK_None;
+ }
+ if (!m_bPagination) {
+ CFX_TxtChar* pTC = m_pCurLine->GetCharPtr(iCount - 1);
+ pTC->m_dwStatus = dwStatus;
+ }
+ if (dwStatus <= FX_TXTBREAK_PieceBreak) {
+ return dwStatus;
+ }
+ }
+ m_iReady = (m_pCurLine == m_pTxtLine1) ? 1 : 2;
+ CFX_TxtLine* pNextLine =
+ (m_pCurLine == m_pTxtLine1) ? m_pTxtLine2 : m_pTxtLine1;
+ FX_BOOL bAllChars = (m_iCurAlignment > FX_TXTLINEALIGNMENT_Right);
+ CFX_TPOArray tpos;
+ CFX_Char* pTC;
+ if (m_bArabicShapes) {
+ EndBreak_UpdateArabicShapes();
+ }
+ if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
+ goto EndBreak_Ret;
+ }
+ EndBreak_BidiLine(tpos, dwStatus);
+ if (!m_bPagination && m_iCurAlignment > FX_TXTLINEALIGNMENT_Left) {
+ EndBreak_Alignment(tpos, bAllChars, dwStatus);
+ }
+EndBreak_Ret:
+ m_pCurLine = pNextLine;
+ pTC = GetLastChar(0, FALSE);
+ m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
+ if (dwStatus == FX_TXTBREAK_ParagraphBreak) {
+ m_iArabicContext = m_iCurArabicContext = 1;
+ ResetArabicContext();
+ }
+ return dwStatus;
+}
+int32_t CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray& ca,
+ int32_t& iEndPos,
+ FX_BOOL bAllChars,
+ FX_BOOL bOnlyBrk) {
+ int32_t iLength = ca.GetSize() - 1;
+ if (iLength < 1) {
+ return iLength;
+ }
+ int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1,
+ iLast = -1, iLastPos = -1;
+ if (m_bSingleLine || iEndPos <= m_iLineWidth) {
+ if (!bAllChars) {
+ return iLength;
+ }
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ }
+ FX_BOOL bSpaceBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0;
+ FX_BOOL bNumberBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_NumberBreak) != 0;
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD nCodeProp, nCur, nNext;
+ CFX_Char* pCur = ca.GetDataPtr(iLength--);
+ if (bAllChars) {
+ pCur->m_nBreakType = FX_LBT_UNKNOWN;
+ }
+ nCodeProp = pCur->m_dwCharProps;
+ nNext = nCodeProp & 0x003F;
+ int32_t iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ while (iLength >= 0) {
+ pCur = ca.GetDataPtr(iLength);
+ nCodeProp = pCur->m_dwCharProps;
+ nCur = nCodeProp & 0x003F;
+ if (nCur == FX_CBP_SP) {
+ if (nNext == FX_CBP_SP) {
+ eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (nCur << 5) + nNext);
+ }
+ } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else {
+ if (nNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE*)gs_FX_LineBreak_PairTable +
+ (nCur << 5) + nNext);
+ }
+ }
+ if (bAllChars) {
+ pCur->m_nBreakType = (uint8_t)eType;
+ }
+ if (!bOnlyBrk) {
+ if (m_bSingleLine || iEndPos <= m_iLineWidth ||
+ (nCur == FX_CBP_SP && !bSpaceBreak)) {
+ if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ if (!bAllChars) {
+ return iLength;
+ }
+ } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
+ iIndirect = iLength;
+ iIndirectPos = iEndPos;
+ }
+ if (iLast < 0) {
+ iLast = iLength;
+ iLastPos = iEndPos;
+ }
+ }
+ iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ nNext = nCodeProp & 0x003F;
+ iLength--;
+ }
+ if (bOnlyBrk) {
+ return 0;
+ }
+ if (iBreak > -1) {
+ iEndPos = iBreakPos;
+ return iBreak;
+ }
+ if (iIndirect > -1) {
+ iEndPos = iIndirectPos;
+ return iIndirect;
+ }
+ if (iLast > -1) {
+ iEndPos = iLastPos;
+ return iLast;
+ }
+ return 0;
+}
+void CFX_TxtBreak::SplitTextLine(CFX_TxtLine* pCurLine,
+ CFX_TxtLine* pNextLine,
+ FX_BOOL bAllChars) {
+ FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
+ int32_t iCount = pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ int32_t iEndPos = pCurLine->m_iWidth;
+ CFX_TxtCharArray& curChars = *pCurLine->m_pLineChars;
+ int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
+ if (iCharPos < 0) {
+ iCharPos = 0;
+ }
+ iCharPos++;
+ if (iCharPos >= iCount) {
+ pNextLine->RemoveAll(TRUE);
+ CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ return;
+ }
+ CFX_TxtCharArray& nextChars = *pNextLine->m_pLineChars;
+ int cur_size = curChars.GetSize();
+ nextChars.SetSize(cur_size - iCharPos);
+ FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos),
+ (cur_size - iCharPos) * sizeof(CFX_TxtChar));
+ iCount -= iCharPos;
+ cur_size = curChars.GetSize();
+ curChars.RemoveAt(cur_size - iCount, iCount);
+ pCurLine->m_iWidth = iEndPos;
+ CFX_TxtChar* pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ iCount = nextChars.GetSize();
+ int32_t iCharWidth, iWidth = 0;
+ for (int32_t i = 0; i < iCount; i++) {
+ pTC = nextChars.GetDataPtr(i);
+ if (pTC->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
+ pCurLine->m_iArabicChars--;
+ pNextLine->m_iArabicChars++;
+ }
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iWidth += iCharWidth;
+ }
+ if (m_bPagination) {
+ continue;
+ }
+ pTC->m_dwStatus = 0;
+ }
+ pNextLine->m_iWidth = iWidth;
+}
+int32_t CFX_TxtBreak::CountBreakChars() const {
+ CFX_TxtLine* pTxtLine = GetTxtLine(TRUE);
+ return pTxtLine == NULL ? 0 : pTxtLine->CountChars();
+}
+int32_t CFX_TxtBreak::CountBreakPieces() const {
+ CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(TRUE);
+ if (pTxtPieces == NULL) {
+ return 0;
+ }
+ return pTxtPieces->GetSize();
+}
+const CFX_TxtPiece* CFX_TxtBreak::GetBreakPiece(int32_t index) const {
+ CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(TRUE);
+ if (pTxtPieces == NULL) {
+ return NULL;
+ }
+ if (index < 0 || index >= pTxtPieces->GetSize()) {
+ return NULL;
+ }
+ return pTxtPieces->GetPtrAt(index);
+}
+void CFX_TxtBreak::ClearBreakPieces() {
+ CFX_TxtLine* pTxtLine = GetTxtLine(TRUE);
+ if (pTxtLine != NULL) {
+ pTxtLine->RemoveAll(TRUE);
+ }
+ m_iReady = 0;
+}
+void CFX_TxtBreak::Reset() {
+ m_dwCharType = 0;
+ m_iArabicContext = m_iCurArabicContext = 1;
+ ResetArabicContext();
+ m_pTxtLine1->RemoveAll(TRUE);
+ m_pTxtLine2->RemoveAll(TRUE);
+}
+typedef struct _FX_FORMCHAR {
+ FX_WORD wch;
+ FX_WORD wForm;
+ int32_t iWidth;
+} FX_FORMCHAR, *FX_LPFORMCHAR;
+typedef FX_FORMCHAR const* FX_LPCFORMCHAR;
+int32_t CFX_TxtBreak::GetDisplayPos(FX_LPCTXTRUN pTxtRun,
+ FXTEXT_CHARPOS* pCharPos,
+ FX_BOOL bCharCode,
+ CFX_WideString* pWSForms,
+ FX_AdjustCharDisplayPos pAdjustPos) const {
+ if (pTxtRun == NULL || pTxtRun->iLength < 1) {
+ return 0;
+ }
+ IFX_TxtAccess* pAccess = pTxtRun->pAccess;
+ void* pIdentity = pTxtRun->pIdentity;
+ const FX_WCHAR* pStr = pTxtRun->pStr;
+ int32_t* pWidths = pTxtRun->pWidths;
+ int32_t iLength = pTxtRun->iLength - 1;
+ IFX_Font* pFont = pTxtRun->pFont;
+ FX_DWORD dwStyles = pTxtRun->dwStyles;
+ CFX_RectF rtText(*pTxtRun->pRect);
+ FX_BOOL bRTLPiece =
+ (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
+ FX_BOOL bArabicNumber =
+ (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
+ FX_BOOL bArabicComma =
+ (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
+ FX_FLOAT fFontSize = pTxtRun->fFontSize;
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ int32_t iAscent = pFont->GetAscent();
+ int32_t iDescent = pFont->GetDescent();
+ int32_t iMaxHeight = iAscent - iDescent;
+ FX_FLOAT fFontHeight = fFontSize;
+ FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
+ FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
+ FX_BOOL bVerticalDoc = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bVerticalChar = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
+ int32_t iRotation = GetLineRotation(dwStyles) + pTxtRun->iCharRotation;
+ int32_t iCharRotation;
+ FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm, wLast = 0xFEFF;
+ int32_t iWidth, iCharWidth, iCharHeight;
+ FX_FLOAT fX, fY, fCharWidth, fCharHeight;
+ int32_t iHorScale = pTxtRun->iHorizontalScale;
+ int32_t iVerScale = pTxtRun->iVerticalScale;
+ FX_BOOL bSkipSpace = pTxtRun->bSkipSpace;
+ FX_BOOL bEmptyChar, bShadda = FALSE, bLam = FALSE;
+ FX_DWORD dwProps, dwCharType;
+ FX_FORMCHAR formChars[3];
+ FX_FLOAT fYBase;
+ fX = rtText.left;
+ if (bVerticalDoc) {
+ fX += (rtText.width - fFontSize) / 2.0f;
+ fYBase = bRTLPiece ? rtText.bottom() : rtText.top;
+ fY = fYBase;
+ } else {
+ if (bRTLPiece) {
+ fX = rtText.right();
+ }
+ fYBase = rtText.top + (rtText.height - fFontSize) / 2.0f;
+ fY = fYBase + fAscent;
+ }
+ int32_t iCount = 0, iNext, iForms;
+ for (int32_t i = 0; i <= iLength; i++) {
+ if (pAccess != NULL) {
+ wch = pAccess->GetChar(pIdentity, i);
+ iWidth = pAccess->GetWidth(pIdentity, i);
+ } else {
+ wch = *pStr++;
+ iWidth = *pWidths++;
+ }
+ dwProps = FX_GetUnicodeProperties(wch);
+ dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
+ if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
+ wPrev = 0xFEFF;
+ wLast = wch;
+ continue;
+ }
+ if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
+ if (i < iLength) {
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ while (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ dwProps = FX_GetUnicodeProperties(wNext);
+ if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination) {
+ break;
+ }
+ iNext++;
+ }
+ if (iNext > iLength) {
+ wNext = 0xFEFF;
+ }
+ } else {
+ int32_t j = -1;
+ do {
+ j++;
+ if (i + j >= iLength) {
+ break;
+ }
+ wNext = pStr[j];
+ dwProps = FX_GetUnicodeProperties(wNext);
+ } while ((dwProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination);
+ if (i + j >= iLength) {
+ wNext = 0xFEFF;
+ }
+ }
+ } else {
+ wNext = 0xFEFF;
+ }
+ wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
+ bLam = (wPrev == 0x0644 && wch == 0x0644 && wNext == 0x0647);
+ } else if (dwCharType == FX_CHARTYPE_Combination) {
+ wForm = wch;
+ if (wch >= 0x064C && wch <= 0x0651) {
+ if (bShadda) {
+ wForm = 0xFEFF;
+ bShadda = FALSE;
+ } else {
+ wNext = 0xFEFF;
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ if (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ }
+ } else {
+ if (i < iLength) {
+ wNext = *pStr;
+ }
+ }
+ if (wch == 0x0651) {
+ if (wNext >= 0x064C && wNext <= 0x0650) {
+ wForm = FX_GetArabicFromShaddaTable(wNext);
+ bShadda = TRUE;
+ }
+ } else {
+ if (wNext == 0x0651) {
+ wForm = FX_GetArabicFromShaddaTable(wch);
+ bShadda = TRUE;
+ }
+ }
+ }
+ } else {
+ bShadda = FALSE;
+ }
+ } else if (dwCharType == FX_CHARTYPE_Numeric) {
+ wForm = wch;
+ if (bArabicNumber) {
+ wForm += 0x0630;
+ }
+ } else if (wch == L'.') {
+ wForm = wch;
+ if (bArabicNumber) {
+ wNext = 0xFEFF;
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ if (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ }
+ } else {
+ if (i < iLength) {
+ wNext = *pStr;
+ }
+ }
+ if (wNext >= L'0' && wNext <= L'9') {
+ wForm = 0x066B;
+ }
+ }
+ } else if (wch == L',') {
+ wForm = wch;
+ if (bArabicComma) {
+ wForm = 0x060C;
+ }
+ } else if (bRTLPiece || bVerticalChar) {
+ wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
+ } else {
+ wForm = wch;
+ }
+ if (dwCharType != FX_CHARTYPE_Combination) {
+ bShadda = FALSE;
+ }
+ if (dwCharType < FX_CHARTYPE_ArabicAlef) {
+ bLam = FALSE;
+ }
+ dwProps = FX_GetUnicodeProperties(wForm);
+ iCharRotation = iRotation;
+ if (bVerticalChar && (dwProps & 0x8000) != 0) {
+ iCharRotation++;
+ }
+ iCharRotation %= 4;
+ bEmptyChar =
+ (dwCharType >= FX_CHARTYPE_Tab && dwCharType <= FX_CHARTYPE_Control);
+ if (wForm == 0xFEFF) {
+ bEmptyChar = TRUE;
+ }
+ iForms = bLam ? 3 : 1;
+ iCount += (bEmptyChar && bSkipSpace) ? 0 : iForms;
+ if (pCharPos == NULL) {
+ if (iWidth > 0) {
+ wPrev = wch;
+ }
+ wLast = wch;
+ continue;
+ }
+ iCharWidth = iWidth;
+ if (iCharWidth < 0) {
+ iCharWidth = -iCharWidth;
+ }
+ iCharWidth /= iFontSize;
+ formChars[0].wch = wch;
+ formChars[0].wForm = wForm;
+ formChars[0].iWidth = iCharWidth;
+ if (bLam) {
+ formChars[1].wForm = 0x0651;
+ iCharWidth = 0;
+ pFont->GetCharWidth(0x0651, iCharWidth, FALSE);
+ formChars[1].iWidth = iCharWidth;
+ formChars[2].wForm = 0x0670;
+ iCharWidth = 0;
+ pFont->GetCharWidth(0x0670, iCharWidth, FALSE);
+ formChars[2].iWidth = iCharWidth;
+ }
+ for (int32_t j = 0; j < iForms; j++) {
+ wForm = (FX_WCHAR)formChars[j].wForm;
+ iCharWidth = formChars[j].iWidth;
+ if (j > 0) {
+ dwCharType = FX_CHARTYPE_Combination;
+ wch = wForm;
+ wLast = (FX_WCHAR)formChars[j - 1].wForm;
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_GlyphIndex =
+ bCharCode ? wch : pFont->GetGlyphIndex(wForm, FALSE);
+ pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
+ pCharPos->m_FontCharWidth = iCharWidth;
+ if (pWSForms) {
+ *pWSForms += wForm;
+ }
+ }
+ if (bVerticalDoc) {
+ iCharHeight = iCharWidth;
+ iCharWidth = 1000;
+ } else {
+ iCharHeight = 1000;
+ }
+ fCharWidth = fFontSize * iCharWidth / 1000.0f;
+ fCharHeight = fFontSize * iCharHeight / 1000.0f;
+ if (bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY -= fCharHeight;
+ } else {
+ fX -= fCharWidth;
+ }
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_OriginX = fX;
+ pCharPos->m_OriginY = fY;
+ if ((dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0) {
+ int32_t iFormWidth = iCharWidth;
+ pFont->GetCharWidth(wForm, iFormWidth, FALSE);
+ FX_FLOAT fOffset = fFontSize * (iCharWidth - iFormWidth) / 2000.0f;
+ if (bVerticalDoc) {
+ pCharPos->m_OriginY += fOffset;
+ } else {
+ pCharPos->m_OriginX += fOffset;
+ }
+ }
+ if (dwCharType == FX_CHARTYPE_Combination) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
+ pCharPos->m_OriginY =
+ fYBase + fFontSize -
+ fFontSize * (FX_FLOAT)rtBBox.height / (FX_FLOAT)iMaxHeight;
+ }
+ if (wForm == wch && wLast != 0xFEFF) {
+ FX_DWORD dwLastProps = FX_GetUnicodeProperties(wLast);
+ if ((dwLastProps & FX_CHARTYPEBITSMASK) ==
+ FX_CHARTYPE_Combination) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wLast, rtBBox, FALSE)) {
+ pCharPos->m_OriginY -= fFontSize * rtBBox.height / iMaxHeight;
+ }
+ }
+ }
+ }
+ CFX_PointF ptOffset;
+ ptOffset.Reset();
+ FX_BOOL bAdjusted = FALSE;
+ if (pAdjustPos) {
+ bAdjusted = pAdjustPos(wForm, bCharCode, pFont, fFontSize,
+ bVerticalChar, ptOffset);
+ }
+ if (!bAdjusted && bVerticalChar && (dwProps & 0x00010000) != 0) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
+ ptOffset.x = fFontSize * (850 - rtBBox.right()) / iMaxHeight;
+ ptOffset.y = fFontSize * (iAscent - rtBBox.top - 150) / iMaxHeight;
+ }
+ }
+ pCharPos->m_OriginX += ptOffset.x;
+ pCharPos->m_OriginY -= ptOffset.y;
+ }
+ if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY += fCharHeight;
+ } else {
+ fX += fCharWidth;
+ }
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_bGlyphAdjust = TRUE;
+ if (bVerticalDoc) {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY += fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent;
+ }
+ } else {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ pCharPos->m_OriginY -= fAscent + fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY -= fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += 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 (iWidth > 0) {
+ wPrev = (FX_WCHAR)formChars[0].wch;
+ }
+ wLast = wch;
+ }
+ return iCount;
+}
+int32_t CFX_TxtBreak::GetCharRects(FX_LPCTXTRUN pTxtRun,
+ CFX_RectFArray& rtArray,
+ FX_BOOL bCharBBox) const {
+ if (pTxtRun == NULL || pTxtRun->iLength < 1) {
+ return 0;
+ }
+ IFX_TxtAccess* pAccess = pTxtRun->pAccess;
+ void* pIdentity = pTxtRun->pIdentity;
+ const FX_WCHAR* pStr = pTxtRun->pStr;
+ int32_t* pWidths = pTxtRun->pWidths;
+ int32_t iLength = pTxtRun->iLength;
+ CFX_RectF rect(*pTxtRun->pRect);
+ FX_BOOL bRTLPiece =
+ (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
+ FX_FLOAT fFontSize = pTxtRun->fFontSize;
+ int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ IFX_Font* pFont = pTxtRun->pFont;
+ if (pFont == NULL) {
+ bCharBBox = FALSE;
+ }
+ CFX_Rect bbox;
+ bbox.Set(0, 0, 0, 0);
+ if (bCharBBox) {
+ bCharBBox = pFont->GetBBox(bbox);
+ }
+ FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale);
+ FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
+ rtArray.RemoveAll();
+ rtArray.SetSize(iLength);
+ FX_BOOL bVertical =
+ (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bSingleLine = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
+ FX_BOOL bCombText = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ FX_WCHAR wch, wLineBreakChar = pTxtRun->wLineBreakChar;
+ int32_t iCharSize;
+ FX_FLOAT fCharSize, fStart;
+ if (bVertical) {
+ fStart = bRTLPiece ? rect.bottom() : rect.top;
+ } else {
+ fStart = bRTLPiece ? rect.right() : rect.left;
+ }
+ for (int32_t i = 0; i < iLength; i++) {
+ if (pAccess != NULL) {
+ wch = pAccess->GetChar(pIdentity, i);
+ iCharSize = pAccess->GetWidth(pIdentity, i);
+ } else {
+ wch = *pStr++;
+ iCharSize = *pWidths++;
+ }
+ fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
+ FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
+ if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 ||
+ (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
+ bRet = FALSE;
+ }
+ if (bRet) {
+ iCharSize = iFontSize * 500;
+ fCharSize = fFontSize / 2.0f;
+ }
+ if (bVertical) {
+ rect.top = fStart;
+ if (bRTLPiece) {
+ rect.top -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.height = fCharSize;
+ } else {
+ rect.left = fStart;
+ if (bRTLPiece) {
+ rect.left -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.width = fCharSize;
+ }
+ if (bCharBBox && !bRet) {
+ int32_t iCharWidth = 1000;
+ pFont->GetCharWidth(wch, iCharWidth);
+ FX_FLOAT fRTLeft = 0, fCharWidth = 0;
+ if (iCharWidth > 0) {
+ fCharWidth = iCharWidth * fScale;
+ fRTLeft = fLeft;
+ if (bCombText) {
+ fRTLeft = (rect.width - fCharWidth) / 2.0f;
+ }
+ }
+ CFX_RectF rtBBoxF;
+ if (bVertical) {
+ rtBBoxF.top = rect.left + fRTLeft;
+ rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.height = fCharWidth;
+ rtBBoxF.width = fHeight;
+ rtBBoxF.left = std::max(rtBBoxF.left, 0.0f);
+ } else {
+ rtBBoxF.left = rect.left + fRTLeft;
+ rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.width = fCharWidth;
+ rtBBoxF.height = fHeight;
+ rtBBoxF.top = std::max(rtBBoxF.top, 0.0f);
+ }
+ rtArray.SetAt(i, rtBBoxF);
+ continue;
+ }
+ rtArray.SetAt(i, rect);
+ }
+ return iLength;
+}
diff --git a/xfa/src/fgas/src/layout/fx_textbreak.h b/xfa/src/fgas/src/layout/fx_textbreak.h
index 68deed58d6..6644725e1b 100644
--- a/xfa/src/fgas/src/layout/fx_textbreak.h
+++ b/xfa/src/fgas/src/layout/fx_textbreak.h
@@ -1,171 +1,171 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_TEXTBREAK_IMP
-#define _FX_TEXTBREAK_IMP
-
-#include "core/include/fxcrt/fx_memory.h"
-
-class IFX_ArabicChar;
-class CFX_Txtbreak;
-
-class CFX_TxtLine {
- public:
- CFX_TxtLine(int32_t iBlockSize)
- : m_iStart(0), m_iWidth(0), m_iArabicChars(0) {
- m_pLineChars = new CFX_TxtCharArray;
- m_pLinePieces = new CFX_TxtPieceArray(16);
- }
- ~CFX_TxtLine() {
- RemoveAll();
- delete m_pLineChars;
- delete m_pLinePieces;
- }
- int32_t CountChars() const { return m_pLineChars->GetSize(); }
- CFX_TxtChar* GetCharPtr(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_pLineChars->GetSize());
- return m_pLineChars->GetDataPtr(index);
- }
- int32_t CountPieces() const { return m_pLinePieces->GetSize(); }
- CFX_TxtPiece* GetPiecePtr(int32_t index) const {
- FXSYS_assert(index > -1 && index < m_pLinePieces->GetSize());
- return m_pLinePieces->GetPtrAt(index);
- }
- void GetString(CFX_WideString& wsStr) const {
- int32_t iCount = m_pLineChars->GetSize();
- FX_WCHAR* pBuf = wsStr.GetBuffer(iCount);
- CFX_Char* pChar;
- for (int32_t i = 0; i < iCount; i++) {
- pChar = m_pLineChars->GetDataPtr(i);
- *pBuf++ = (FX_WCHAR)pChar->m_wCharCode;
- }
- wsStr.ReleaseBuffer(iCount);
- }
- void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
- m_pLineChars->RemoveAll();
- m_pLinePieces->RemoveAll(bLeaveMemory);
- m_iWidth = 0;
- m_iArabicChars = 0;
- }
- CFX_TxtCharArray* m_pLineChars;
- CFX_TxtPieceArray* m_pLinePieces;
- int32_t m_iStart;
- int32_t m_iWidth;
- int32_t m_iArabicChars;
-};
-class CFX_TxtBreak : public IFX_TxtBreak {
- public:
- CFX_TxtBreak(FX_DWORD dwPolicies);
- ~CFX_TxtBreak();
- virtual void Release() { delete this; }
- virtual void SetLineWidth(FX_FLOAT fLineWidth);
- virtual void SetLinePos(FX_FLOAT fLinePos);
- virtual FX_DWORD GetLayoutStyles() const { return m_dwLayoutStyles; }
- virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles);
- virtual void SetFont(IFX_Font* pFont);
- virtual void SetFontSize(FX_FLOAT fFontSize);
- virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
- virtual void SetDefaultChar(FX_WCHAR wch);
- virtual void SetParagraphBreakChar(FX_WCHAR wch);
- virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
- virtual void SetHorizontalScale(int32_t iScale);
- virtual void SetVerticalScale(int32_t iScale);
- virtual void SetCharRotation(int32_t iCharRotation);
- virtual void SetCharSpace(FX_FLOAT fCharSpace);
- virtual void SetAlignment(int32_t iAlignment);
- virtual FX_DWORD GetContextCharStyles() const;
- virtual void SetContextCharStyles(FX_DWORD dwCharStyles);
- virtual void SetCombWidth(FX_FLOAT fCombWidth);
- virtual void SetUserData(void* pUserData);
- virtual FX_DWORD AppendChar(FX_WCHAR wch);
- virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak);
- virtual int32_t CountBreakChars() const;
- virtual int32_t CountBreakPieces() const;
- virtual const CFX_TxtPiece* GetBreakPiece(int32_t index) const;
- virtual void ClearBreakPieces();
- virtual void Reset();
- virtual int32_t GetDisplayPos(
- FX_LPCTXTRUN pTxtRun,
- FXTEXT_CHARPOS* pCharPos,
- FX_BOOL bCharCode = FALSE,
- CFX_WideString* pWSForms = NULL,
- FX_AdjustCharDisplayPos pAdjustPos = NULL) const;
- virtual int32_t GetCharRects(FX_LPCTXTRUN pTxtRun,
- CFX_RectFArray& rtArray,
- FX_BOOL bCharBBox = FALSE) const;
- void AppendChar_PageLoad(CFX_Char* pCurChar, FX_DWORD dwProps);
- FX_DWORD AppendChar_Combination(CFX_Char* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Tab(CFX_Char* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Control(CFX_Char* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Arabic(CFX_Char* pCurChar, int32_t iRotation);
- FX_DWORD AppendChar_Others(CFX_Char* pCurChar, int32_t iRotation);
-
- protected:
- FX_DWORD m_dwPolicies;
- FX_BOOL m_bPagination;
- IFX_ArabicChar* m_pArabicChar;
- int32_t m_iLineWidth;
- FX_DWORD m_dwLayoutStyles;
- FX_BOOL m_bVertical;
- FX_BOOL m_bArabicContext;
- FX_BOOL m_bArabicShapes;
- FX_BOOL m_bRTL;
- FX_BOOL m_bSingleLine;
- FX_BOOL m_bCombText;
- int32_t m_iArabicContext;
- int32_t m_iCurArabicContext;
- IFX_Font* m_pFont;
- int32_t m_iFontSize;
- FX_BOOL m_bEquidistant;
- int32_t m_iTabWidth;
- FX_WCHAR m_wDefChar;
- FX_WCHAR m_wParagBreakChar;
- int32_t m_iDefChar;
- int32_t m_iLineRotation;
- int32_t m_iCharRotation;
- int32_t m_iRotation;
- int32_t m_iAlignment;
- FX_DWORD m_dwContextCharStyles;
- int32_t m_iCombWidth;
- void* m_pUserData;
- FX_DWORD m_dwCharType;
- FX_BOOL m_bCurRTL;
- int32_t m_iCurAlignment;
- FX_BOOL m_bArabicNumber;
- FX_BOOL m_bArabicComma;
- CFX_TxtLine* m_pTxtLine1;
- CFX_TxtLine* m_pTxtLine2;
- CFX_TxtLine* m_pCurLine;
- int32_t m_iReady;
- int32_t m_iTolerance;
- int32_t m_iHorScale;
- int32_t m_iVerScale;
- int32_t m_iCharSpace;
- void SetBreakStatus();
- int32_t GetLineRotation(FX_DWORD dwStyles) const;
- CFX_TxtChar* GetLastChar(int32_t index, FX_BOOL bOmitChar = TRUE) const;
- CFX_TxtLine* GetTxtLine(FX_BOOL bReady) const;
- CFX_TxtPieceArray* GetTxtPieces(FX_BOOL bReady) const;
- FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
- void ResetArabicContext();
- void ResetContextCharStyles();
- void EndBreak_UpdateArabicShapes();
- FX_BOOL EndBreak_SplitLine(CFX_TxtLine* pNextLine,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus);
- void EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus);
- void EndBreak_Alignment(CFX_TPOArray& tpos,
- FX_BOOL bAllChars,
- FX_DWORD dwStatus);
- int32_t GetBreakPos(CFX_TxtCharArray& ca,
- int32_t& iEndPos,
- FX_BOOL bAllChars = FALSE,
- FX_BOOL bOnlyBrk = FALSE);
- void SplitTextLine(CFX_TxtLine* pCurLine,
- CFX_TxtLine* pNextLine,
- FX_BOOL bAllChars = FALSE);
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_TEXTBREAK_IMP
+#define _FX_TEXTBREAK_IMP
+
+#include "core/include/fxcrt/fx_memory.h"
+
+class IFX_ArabicChar;
+class CFX_Txtbreak;
+
+class CFX_TxtLine {
+ public:
+ CFX_TxtLine(int32_t iBlockSize)
+ : m_iStart(0), m_iWidth(0), m_iArabicChars(0) {
+ m_pLineChars = new CFX_TxtCharArray;
+ m_pLinePieces = new CFX_TxtPieceArray(16);
+ }
+ ~CFX_TxtLine() {
+ RemoveAll();
+ delete m_pLineChars;
+ delete m_pLinePieces;
+ }
+ int32_t CountChars() const { return m_pLineChars->GetSize(); }
+ CFX_TxtChar* GetCharPtr(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_pLineChars->GetSize());
+ return m_pLineChars->GetDataPtr(index);
+ }
+ int32_t CountPieces() const { return m_pLinePieces->GetSize(); }
+ CFX_TxtPiece* GetPiecePtr(int32_t index) const {
+ FXSYS_assert(index > -1 && index < m_pLinePieces->GetSize());
+ return m_pLinePieces->GetPtrAt(index);
+ }
+ void GetString(CFX_WideString& wsStr) const {
+ int32_t iCount = m_pLineChars->GetSize();
+ FX_WCHAR* pBuf = wsStr.GetBuffer(iCount);
+ CFX_Char* pChar;
+ for (int32_t i = 0; i < iCount; i++) {
+ pChar = m_pLineChars->GetDataPtr(i);
+ *pBuf++ = (FX_WCHAR)pChar->m_wCharCode;
+ }
+ wsStr.ReleaseBuffer(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE) {
+ m_pLineChars->RemoveAll();
+ m_pLinePieces->RemoveAll(bLeaveMemory);
+ m_iWidth = 0;
+ m_iArabicChars = 0;
+ }
+ CFX_TxtCharArray* m_pLineChars;
+ CFX_TxtPieceArray* m_pLinePieces;
+ int32_t m_iStart;
+ int32_t m_iWidth;
+ int32_t m_iArabicChars;
+};
+class CFX_TxtBreak : public IFX_TxtBreak {
+ public:
+ CFX_TxtBreak(FX_DWORD dwPolicies);
+ ~CFX_TxtBreak();
+ virtual void Release() { delete this; }
+ virtual void SetLineWidth(FX_FLOAT fLineWidth);
+ virtual void SetLinePos(FX_FLOAT fLinePos);
+ virtual FX_DWORD GetLayoutStyles() const { return m_dwLayoutStyles; }
+ virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles);
+ virtual void SetFont(IFX_Font* pFont);
+ virtual void SetFontSize(FX_FLOAT fFontSize);
+ virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ virtual void SetDefaultChar(FX_WCHAR wch);
+ virtual void SetParagraphBreakChar(FX_WCHAR wch);
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
+ virtual void SetHorizontalScale(int32_t iScale);
+ virtual void SetVerticalScale(int32_t iScale);
+ virtual void SetCharRotation(int32_t iCharRotation);
+ virtual void SetCharSpace(FX_FLOAT fCharSpace);
+ virtual void SetAlignment(int32_t iAlignment);
+ virtual FX_DWORD GetContextCharStyles() const;
+ virtual void SetContextCharStyles(FX_DWORD dwCharStyles);
+ virtual void SetCombWidth(FX_FLOAT fCombWidth);
+ virtual void SetUserData(void* pUserData);
+ virtual FX_DWORD AppendChar(FX_WCHAR wch);
+ virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak);
+ virtual int32_t CountBreakChars() const;
+ virtual int32_t CountBreakPieces() const;
+ virtual const CFX_TxtPiece* GetBreakPiece(int32_t index) const;
+ virtual void ClearBreakPieces();
+ virtual void Reset();
+ virtual int32_t GetDisplayPos(
+ FX_LPCTXTRUN pTxtRun,
+ FXTEXT_CHARPOS* pCharPos,
+ FX_BOOL bCharCode = FALSE,
+ CFX_WideString* pWSForms = NULL,
+ FX_AdjustCharDisplayPos pAdjustPos = NULL) const;
+ virtual int32_t GetCharRects(FX_LPCTXTRUN pTxtRun,
+ CFX_RectFArray& rtArray,
+ FX_BOOL bCharBBox = FALSE) const;
+ void AppendChar_PageLoad(CFX_Char* pCurChar, FX_DWORD dwProps);
+ FX_DWORD AppendChar_Combination(CFX_Char* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Tab(CFX_Char* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Control(CFX_Char* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Arabic(CFX_Char* pCurChar, int32_t iRotation);
+ FX_DWORD AppendChar_Others(CFX_Char* pCurChar, int32_t iRotation);
+
+ protected:
+ FX_DWORD m_dwPolicies;
+ FX_BOOL m_bPagination;
+ IFX_ArabicChar* m_pArabicChar;
+ int32_t m_iLineWidth;
+ FX_DWORD m_dwLayoutStyles;
+ FX_BOOL m_bVertical;
+ FX_BOOL m_bArabicContext;
+ FX_BOOL m_bArabicShapes;
+ FX_BOOL m_bRTL;
+ FX_BOOL m_bSingleLine;
+ FX_BOOL m_bCombText;
+ int32_t m_iArabicContext;
+ int32_t m_iCurArabicContext;
+ IFX_Font* m_pFont;
+ int32_t m_iFontSize;
+ FX_BOOL m_bEquidistant;
+ int32_t m_iTabWidth;
+ FX_WCHAR m_wDefChar;
+ FX_WCHAR m_wParagBreakChar;
+ int32_t m_iDefChar;
+ int32_t m_iLineRotation;
+ int32_t m_iCharRotation;
+ int32_t m_iRotation;
+ int32_t m_iAlignment;
+ FX_DWORD m_dwContextCharStyles;
+ int32_t m_iCombWidth;
+ void* m_pUserData;
+ FX_DWORD m_dwCharType;
+ FX_BOOL m_bCurRTL;
+ int32_t m_iCurAlignment;
+ FX_BOOL m_bArabicNumber;
+ FX_BOOL m_bArabicComma;
+ CFX_TxtLine* m_pTxtLine1;
+ CFX_TxtLine* m_pTxtLine2;
+ CFX_TxtLine* m_pCurLine;
+ int32_t m_iReady;
+ int32_t m_iTolerance;
+ int32_t m_iHorScale;
+ int32_t m_iVerScale;
+ int32_t m_iCharSpace;
+ void SetBreakStatus();
+ int32_t GetLineRotation(FX_DWORD dwStyles) const;
+ CFX_TxtChar* GetLastChar(int32_t index, FX_BOOL bOmitChar = TRUE) const;
+ CFX_TxtLine* GetTxtLine(FX_BOOL bReady) const;
+ CFX_TxtPieceArray* GetTxtPieces(FX_BOOL bReady) const;
+ FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
+ void ResetArabicContext();
+ void ResetContextCharStyles();
+ void EndBreak_UpdateArabicShapes();
+ FX_BOOL EndBreak_SplitLine(CFX_TxtLine* pNextLine,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus);
+ void EndBreak_BidiLine(CFX_TPOArray& tpos, FX_DWORD dwStatus);
+ void EndBreak_Alignment(CFX_TPOArray& tpos,
+ FX_BOOL bAllChars,
+ FX_DWORD dwStatus);
+ int32_t GetBreakPos(CFX_TxtCharArray& ca,
+ int32_t& iEndPos,
+ FX_BOOL bAllChars = FALSE,
+ FX_BOOL bOnlyBrk = FALSE);
+ void SplitTextLine(CFX_TxtLine* pCurLine,
+ CFX_TxtLine* pNextLine,
+ FX_BOOL bAllChars = FALSE);
+};
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_unicode.cpp b/xfa/src/fgas/src/layout/fx_unicode.cpp
index ff98760826..3734d5f4a6 100644
--- a/xfa/src/fgas/src/layout/fx_unicode.cpp
+++ b/xfa/src/fgas/src/layout/fx_unicode.cpp
@@ -1,117 +1,117 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_unicode.h"
-void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd) {
- FXSYS_assert(iStart > -1 && iStart < tpos.GetSize());
- FXSYS_assert(iEnd > -1 && iEnd < tpos.GetSize());
- if (iStart >= iEnd) {
- return;
- }
- int32_t i = iStart, j = iEnd;
- FX_TPO *pCur = tpos.GetPtrAt(iStart), *pSort;
- int32_t v = pCur->pos;
- while (i < j) {
- while (j > i) {
- pSort = tpos.GetPtrAt(j);
- if (pSort->pos < v) {
- FX_TPO t = *pSort;
- *pSort = *pCur;
- *pCur = t;
- pCur = pSort;
- break;
- }
- j--;
- }
- while (i < j) {
- pSort = tpos.GetPtrAt(i);
- if (pSort->pos > v) {
- FX_TPO t = *pSort;
- *pSort = *pCur;
- *pCur = t;
- pCur = pSort;
- break;
- }
- i++;
- }
- }
- i--, j++;
- if (iStart < i) {
- FX_TEXTLAYOUT_PieceSort(tpos, iStart, i);
- }
- if (j < iEnd) {
- FX_TEXTLAYOUT_PieceSort(tpos, j, iEnd);
- }
-}
-static const FX_JAPCHARPROPERTYEX gs_FX_JapCharPropertysEx[] = {
- {0x3001, 0x13}, {0x3002, 0x13}, {0x3041, 0x23}, {0x3043, 0x23},
- {0x3045, 0x23}, {0x3047, 0x23}, {0x3049, 0x23}, {0x3063, 0x23},
- {0x3083, 0x23}, {0x3085, 0x23}, {0x3087, 0x23}, {0x308E, 0x23},
- {0x3095, 0x23}, {0x3096, 0x23}, {0x30A1, 0x23}, {0x30A3, 0x23},
- {0x30A5, 0x23}, {0x30A7, 0x23}, {0x30A9, 0x23}, {0x30C3, 0x23},
- {0x30E3, 0x23}, {0x30E5, 0x23}, {0x30E7, 0x23}, {0x30EE, 0x23},
- {0x30F5, 0x23}, {0x30F6, 0x23}, {0x30FB, 0x22}, {0x31F0, 0x23},
- {0x31F1, 0x23}, {0x31F2, 0x23}, {0x31F3, 0x23}, {0x31F4, 0x23},
- {0x31F5, 0x23}, {0x31F6, 0x23}, {0x31F7, 0x23}, {0x31F8, 0x23},
- {0x31F9, 0x23}, {0x31FA, 0x23}, {0x31FB, 0x23}, {0x31FC, 0x23},
- {0x31FD, 0x23}, {0x31FE, 0x23}, {0x31FF, 0x23},
-};
-FX_LPCJAPCHARPROPERTYEX FX_GetJapCharPropertyEx(FX_WCHAR wch) {
- int32_t iStart = 0;
- int32_t iEnd =
- sizeof(gs_FX_JapCharPropertysEx) / sizeof(FX_JAPCHARPROPERTYEX);
- while (iStart <= iEnd) {
- int32_t iMid = (iStart + iEnd) / 2;
- FX_WCHAR wJapChar = gs_FX_JapCharPropertysEx[iMid].wChar;
- if (wch == wJapChar) {
- return gs_FX_JapCharPropertysEx + iMid;
- } else if (wch < wJapChar) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- }
- return NULL;
-}
-FX_BOOL FX_AdjustJapCharDisplayPos(FX_WCHAR wch,
- FX_BOOL bMBCSCode,
- IFX_Font* pFont,
- FX_FLOAT fFontSize,
- FX_BOOL bVertical,
- CFX_PointF& ptOffset) {
- if (pFont == NULL || !bVertical) {
- return FALSE;
- }
- if (wch < 0x3001 || wch > 0x31FF) {
- return FALSE;
- }
- FX_LPCJAPCHARPROPERTYEX pJapChar = FX_GetJapCharPropertyEx(wch);
- if (pJapChar == NULL) {
- return FALSE;
- }
- CFX_Rect rtBBox;
- rtBBox.Reset();
- if (pFont->GetCharBBox(wch, rtBBox, bMBCSCode)) {
- switch (pJapChar->uAlign & 0xF0) {
- case FX_JAPCHARPROPERTYEX_Top:
- ptOffset.y = fFontSize * (1000 - rtBBox.height) / 1200.0f;
- break;
- case FX_JAPCHARPROPERTYEX_Middle:
- ptOffset.y = fFontSize * (1000 - rtBBox.height) / 6000.0f;
- break;
- }
- switch (pJapChar->uAlign & 0x0F) {
- case FX_JAPCHARPROPERTYEX_Center:
- ptOffset.x = fFontSize * (600 - rtBBox.right()) / 1000.0f;
- break;
- case FX_JAPCHARPROPERTYEX_Right:
- ptOffset.x = fFontSize * (950 - rtBBox.right()) / 1000.0f;
- break;
- }
- }
- return TRUE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_unicode.h"
+void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd) {
+ FXSYS_assert(iStart > -1 && iStart < tpos.GetSize());
+ FXSYS_assert(iEnd > -1 && iEnd < tpos.GetSize());
+ if (iStart >= iEnd) {
+ return;
+ }
+ int32_t i = iStart, j = iEnd;
+ FX_TPO *pCur = tpos.GetPtrAt(iStart), *pSort;
+ int32_t v = pCur->pos;
+ while (i < j) {
+ while (j > i) {
+ pSort = tpos.GetPtrAt(j);
+ if (pSort->pos < v) {
+ FX_TPO t = *pSort;
+ *pSort = *pCur;
+ *pCur = t;
+ pCur = pSort;
+ break;
+ }
+ j--;
+ }
+ while (i < j) {
+ pSort = tpos.GetPtrAt(i);
+ if (pSort->pos > v) {
+ FX_TPO t = *pSort;
+ *pSort = *pCur;
+ *pCur = t;
+ pCur = pSort;
+ break;
+ }
+ i++;
+ }
+ }
+ i--, j++;
+ if (iStart < i) {
+ FX_TEXTLAYOUT_PieceSort(tpos, iStart, i);
+ }
+ if (j < iEnd) {
+ FX_TEXTLAYOUT_PieceSort(tpos, j, iEnd);
+ }
+}
+static const FX_JAPCHARPROPERTYEX gs_FX_JapCharPropertysEx[] = {
+ {0x3001, 0x13}, {0x3002, 0x13}, {0x3041, 0x23}, {0x3043, 0x23},
+ {0x3045, 0x23}, {0x3047, 0x23}, {0x3049, 0x23}, {0x3063, 0x23},
+ {0x3083, 0x23}, {0x3085, 0x23}, {0x3087, 0x23}, {0x308E, 0x23},
+ {0x3095, 0x23}, {0x3096, 0x23}, {0x30A1, 0x23}, {0x30A3, 0x23},
+ {0x30A5, 0x23}, {0x30A7, 0x23}, {0x30A9, 0x23}, {0x30C3, 0x23},
+ {0x30E3, 0x23}, {0x30E5, 0x23}, {0x30E7, 0x23}, {0x30EE, 0x23},
+ {0x30F5, 0x23}, {0x30F6, 0x23}, {0x30FB, 0x22}, {0x31F0, 0x23},
+ {0x31F1, 0x23}, {0x31F2, 0x23}, {0x31F3, 0x23}, {0x31F4, 0x23},
+ {0x31F5, 0x23}, {0x31F6, 0x23}, {0x31F7, 0x23}, {0x31F8, 0x23},
+ {0x31F9, 0x23}, {0x31FA, 0x23}, {0x31FB, 0x23}, {0x31FC, 0x23},
+ {0x31FD, 0x23}, {0x31FE, 0x23}, {0x31FF, 0x23},
+};
+FX_LPCJAPCHARPROPERTYEX FX_GetJapCharPropertyEx(FX_WCHAR wch) {
+ int32_t iStart = 0;
+ int32_t iEnd =
+ sizeof(gs_FX_JapCharPropertysEx) / sizeof(FX_JAPCHARPROPERTYEX);
+ while (iStart <= iEnd) {
+ int32_t iMid = (iStart + iEnd) / 2;
+ FX_WCHAR wJapChar = gs_FX_JapCharPropertysEx[iMid].wChar;
+ if (wch == wJapChar) {
+ return gs_FX_JapCharPropertysEx + iMid;
+ } else if (wch < wJapChar) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ }
+ return NULL;
+}
+FX_BOOL FX_AdjustJapCharDisplayPos(FX_WCHAR wch,
+ FX_BOOL bMBCSCode,
+ IFX_Font* pFont,
+ FX_FLOAT fFontSize,
+ FX_BOOL bVertical,
+ CFX_PointF& ptOffset) {
+ if (pFont == NULL || !bVertical) {
+ return FALSE;
+ }
+ if (wch < 0x3001 || wch > 0x31FF) {
+ return FALSE;
+ }
+ FX_LPCJAPCHARPROPERTYEX pJapChar = FX_GetJapCharPropertyEx(wch);
+ if (pJapChar == NULL) {
+ return FALSE;
+ }
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wch, rtBBox, bMBCSCode)) {
+ switch (pJapChar->uAlign & 0xF0) {
+ case FX_JAPCHARPROPERTYEX_Top:
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 1200.0f;
+ break;
+ case FX_JAPCHARPROPERTYEX_Middle:
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 6000.0f;
+ break;
+ }
+ switch (pJapChar->uAlign & 0x0F) {
+ case FX_JAPCHARPROPERTYEX_Center:
+ ptOffset.x = fFontSize * (600 - rtBBox.right()) / 1000.0f;
+ break;
+ case FX_JAPCHARPROPERTYEX_Right:
+ ptOffset.x = fFontSize * (950 - rtBBox.right()) / 1000.0f;
+ break;
+ }
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fgas/src/layout/fx_unicode.h b/xfa/src/fgas/src/layout/fx_unicode.h
index 61d1810b3e..92ec5004ea 100644
--- a/xfa/src/fgas/src/layout/fx_unicode.h
+++ b/xfa/src/fgas/src/layout/fx_unicode.h
@@ -1,15 +1,15 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FGAS_UNICODE_IMP
-#define _FGAS_UNICODE_IMP
-typedef struct _FX_TPO {
- int32_t index;
- int32_t pos;
-} FX_TPO;
-typedef CFX_MassArrayTemplate<FX_TPO> CFX_TPOArray;
-void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd);
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_UNICODE_IMP
+#define _FGAS_UNICODE_IMP
+typedef struct _FX_TPO {
+ int32_t index;
+ int32_t pos;
+} FX_TPO;
+typedef CFX_MassArrayTemplate<FX_TPO> CFX_TPOArray;
+void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd);
+#endif
diff --git a/xfa/src/fgas/src/localization/fx_datetime.cpp b/xfa/src/fgas/src/localization/fx_datetime.cpp
index e8dc8dcbc0..76b7eb14d6 100644
--- a/xfa/src/fgas/src/localization/fx_datetime.cpp
+++ b/xfa/src/fgas/src/localization/fx_datetime.cpp
@@ -1,553 +1,553 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/src/fgas/src/fgas_base.h"
-const uint8_t g_FXDaysPerMonth[12] = {31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31};
-const uint8_t g_FXDaysPerLeapMonth[12] = {31, 29, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31};
-const int32_t g_FXDaysBeforeMonth[12] = {0, 31, 59, 90, 120, 151,
- 181, 212, 243, 273, 304, 334};
-const int32_t g_FXDaysBeforeLeapMonth[12] = {0, 31, 60, 91, 121, 152,
- 182, 213, 244, 274, 305, 335};
-const int32_t g_FXDaysPerYear = 365;
-const int32_t g_FXDaysPerLeapYear = 366;
-const int32_t g_FXDaysPer4Years = 1461;
-const int32_t g_FXDaysPer100Years = 36524;
-const int32_t g_FXDaysPer400Years = 146097;
-const int64_t g_FXMillisecondsPerSecond = 1000;
-const int64_t g_FXMillisecondsPerMinute = 60000;
-const int64_t g_FXMillisecondsPerHour = 3600000;
-const int64_t g_FXMillisecondsPerDay = 86400000;
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
-const int64_t g_FXMillisecondsPerYear = 0x0757B12C00;
-const int64_t g_FXMillisecondsPerLeapYear = 0x075CD78800;
-const int64_t g_FXMillisecondsPer4Years = 0x1D63EB0C00;
-const int64_t g_FXMillisecondsPer100Years = 0x02DEBCCDD000;
-const int64_t g_FXMillisecondsPer400Years = 0x0B7AF85D9C00;
-#endif
-FX_BOOL FX_IsLeapYear(int32_t iYear) {
- FXSYS_assert(iYear != 0);
- return ((iYear % 4) == 0 && (iYear % 100) != 0) || (iYear % 400) == 0;
-}
-int32_t FX_DaysInYear(int32_t iYear) {
- FXSYS_assert(iYear != 0);
- return FX_IsLeapYear(iYear) ? g_FXDaysPerLeapYear : g_FXDaysPerYear;
-}
-uint8_t FX_DaysInMonth(int32_t iYear, uint8_t iMonth) {
- FXSYS_assert(iYear != 0);
- FXSYS_assert(iMonth >= 1 && iMonth <= 12);
- const uint8_t* p =
- FX_IsLeapYear(iYear) ? g_FXDaysPerLeapMonth : g_FXDaysPerMonth;
- return p[iMonth - 1];
-}
-static int32_t FX_DaysBeforeMonthInYear(int32_t iYear, uint8_t iMonth) {
- FXSYS_assert(iYear != 0);
- FXSYS_assert(iMonth >= 1 && iMonth <= 12);
- const int32_t* p =
- FX_IsLeapYear(iYear) ? g_FXDaysBeforeLeapMonth : g_FXDaysBeforeMonth;
- return p[iMonth - 1];
-}
-static int64_t FX_DateToDays(int32_t iYear,
- uint8_t iMonth,
- uint8_t iDay,
- FX_BOOL bIncludeThisDay = FALSE) {
- FXSYS_assert(iYear != 0);
- FXSYS_assert(iMonth >= 1 && iMonth <= 12);
- FXSYS_assert(iDay >= 1 && iDay <= FX_DaysInMonth(iYear, iMonth));
- int64_t iDays = FX_DaysBeforeMonthInYear(iYear, iMonth);
- iDays += iDay;
- if (!bIncludeThisDay) {
- iDays--;
- }
- if (iYear > 0) {
- iYear--;
- } else {
- iDays -= FX_DaysInYear(iYear);
- iYear++;
- }
- return iDays + (int64_t)iYear * 365 + iYear / 4 - iYear / 100 + iYear / 400;
-}
-static void FX_DaysToDate(int64_t iDays,
- int32_t& iYear,
- uint8_t& iMonth,
- uint8_t& iDay) {
- FX_BOOL bBC = iDays < 0;
- if (bBC) {
- iDays = -iDays;
- }
- iYear = 1;
- iMonth = 1;
- iDay = 1;
- if (iDays >= g_FXDaysPer400Years) {
- iYear += (int32_t)(iDays / g_FXDaysPer400Years * 400);
- iDays %= g_FXDaysPer400Years;
- }
- if (iDays >= g_FXDaysPer100Years) {
- if (iDays == g_FXDaysPer100Years * 4) {
- iYear += 300;
- iDays -= g_FXDaysPer100Years * 3;
- } else {
- iYear += (int32_t)(iDays / g_FXDaysPer100Years * 100);
- iDays %= g_FXDaysPer100Years;
- }
- }
- if (iDays >= g_FXDaysPer4Years) {
- iYear += (int32_t)(iDays / g_FXDaysPer4Years * 4);
- iDays %= g_FXDaysPer4Years;
- }
- while (TRUE) {
- int32_t iYearDays = FX_DaysInYear(iYear);
- if (iDays < iYearDays) {
- if (bBC) {
- iYear = -iYear;
- iDays = iYearDays - iDays;
- }
- break;
- }
- iYear++;
- iDays -= iYearDays;
- }
- while (TRUE) {
- int32_t iMonthDays = FX_DaysInMonth(iYear, iMonth);
- if (iDays < iMonthDays) {
- break;
- }
- iMonth++;
- iDays -= iMonthDays;
- }
- iDay += (uint8_t)iDays;
-}
-#if _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_ || \
- _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
-#include <time.h>
-#include <sys/time.h>
-#endif
-typedef struct _FXUT_SYSTEMTIME {
- FX_WORD wYear;
- FX_WORD wMonth;
- FX_WORD wDayOfWeek;
- FX_WORD wDay;
- FX_WORD wHour;
- FX_WORD wMinute;
- FX_WORD wSecond;
- FX_WORD wMilliseconds;
-} FXUT_SYSTEMTIME;
-void CFX_Unitime::Now() {
- FXUT_SYSTEMTIME utLocal;
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
- ::GetLocalTime((LPSYSTEMTIME)&utLocal);
-#elif _FX_OS_ != _FX_EMBEDDED_
-#if 1
- timeval curTime;
- gettimeofday(&curTime, NULL);
-#else
- struct timespec curTime;
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
-#endif
- struct tm st;
- localtime_r(&curTime.tv_sec, &st);
- utLocal.wYear = st.tm_year + 1900;
- utLocal.wMonth = st.tm_mon + 1;
- utLocal.wDayOfWeek = st.tm_wday;
- utLocal.wDay = st.tm_mday;
- utLocal.wHour = st.tm_hour;
- utLocal.wMinute = st.tm_min;
- utLocal.wSecond = st.tm_sec;
- utLocal.wMilliseconds = curTime.tv_usec / 1000;
-#endif
- Set(utLocal.wYear, (uint8_t)utLocal.wMonth, (uint8_t)utLocal.wDay,
- (uint8_t)utLocal.wHour, (uint8_t)utLocal.wMinute,
- (uint8_t)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
-}
-void CFX_Unitime::SetGMTime() {
- FXUT_SYSTEMTIME utLocal;
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
- _FX_OS_ == _FX_WIN64_
- ::GetSystemTime((LPSYSTEMTIME)&utLocal);
-#elif _FX_OS_ != _FX_EMBEDDED_
-#if 1
- timeval curTime;
- gettimeofday(&curTime, NULL);
-#else
- struct timespec curTime;
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
-#endif
- struct tm st;
- gmtime_r(&curTime.tv_sec, &st);
- utLocal.wYear = st.tm_year + 1900;
- utLocal.wMonth = st.tm_mon + 1;
- utLocal.wDayOfWeek = st.tm_wday;
- utLocal.wDay = st.tm_mday;
- utLocal.wHour = st.tm_hour;
- utLocal.wMinute = st.tm_min;
- utLocal.wSecond = st.tm_sec;
- utLocal.wMilliseconds = curTime.tv_usec / 1000;
-#endif
- Set(utLocal.wYear, (uint8_t)utLocal.wMonth, (uint8_t)utLocal.wDay,
- (uint8_t)utLocal.wHour, (uint8_t)utLocal.wMinute,
- (uint8_t)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
-}
-void CFX_Unitime::Set(int32_t year,
- uint8_t month,
- uint8_t day,
- uint8_t hour,
- uint8_t minute,
- uint8_t second,
- FX_WORD millisecond) {
- FXSYS_assert(hour <= 23);
- FXSYS_assert(minute <= 59);
- FXSYS_assert(second <= 59);
- FXSYS_assert(millisecond <= 999);
- m_iUnitime = (int64_t)hour * g_FXMillisecondsPerHour +
- (int64_t)minute * g_FXMillisecondsPerMinute +
- (int64_t)second * g_FXMillisecondsPerSecond + millisecond;
- if (year > 0) {
- m_iUnitime =
- m_iUnitime +
- FX_DateToDays(year, month, day, FALSE) * g_FXMillisecondsPerDay;
- }
-}
-void CFX_Unitime::Set(FX_UNITIME t) {
- m_iUnitime = t;
-}
-int32_t CFX_Unitime::GetYear() const {
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- return iYear;
-}
-uint8_t CFX_Unitime::GetMonth() const {
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- return iMonth;
-}
-uint8_t CFX_Unitime::GetDay() const {
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- return iDay;
-}
-FX_WEEKDAY CFX_Unitime::GetDayOfWeek() const {
- int32_t v = (int32_t)((m_iUnitime / g_FXMillisecondsPerDay + 1) % 7);
- if (v < 0) {
- v += 7;
- }
- return (FX_WEEKDAY)v;
-}
-FX_WORD CFX_Unitime::GetDayOfYear() const {
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- return FX_DaysBeforeMonthInYear(iYear, iMonth) + iDay;
-}
-int64_t CFX_Unitime::GetDayOfAD() const {
- FX_BOOL bBC = m_iUnitime < 0;
- int64_t iDays = m_iUnitime / g_FXMillisecondsPerDay;
- iDays += bBC ? -1 : 0;
- if (bBC && (m_iUnitime % g_FXMillisecondsPerDay) == 0) {
- iDays++;
- }
- return iDays;
-}
-uint8_t CFX_Unitime::GetHour() const {
- int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerDay);
- if (v < 0) {
- v += g_FXMillisecondsPerDay;
- }
- return (uint8_t)(v / g_FXMillisecondsPerHour);
-}
-uint8_t CFX_Unitime::GetMinute() const {
- int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerHour);
- if (v < 0) {
- v += g_FXMillisecondsPerHour;
- }
- return (uint8_t)(v / g_FXMillisecondsPerMinute);
-}
-uint8_t CFX_Unitime::GetSecond() const {
- int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerMinute);
- if (v < 0) {
- v += g_FXMillisecondsPerMinute;
- }
- return (uint8_t)(v / g_FXMillisecondsPerSecond);
-}
-FX_WORD CFX_Unitime::GetMillisecond() const {
- int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerSecond);
- if (v < 0) {
- v += g_FXMillisecondsPerSecond;
- }
- return (FX_WORD)v;
-}
-FX_BOOL CFX_Unitime::AddYears(int32_t iYears) {
- FX_UNITIME ut = m_iUnitime;
- if (ut < 0) {
- ut = -ut;
- }
- FX_UNITIME r = ut % g_FXMillisecondsPerDay;
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- iYear += iYears;
- if (iYear == 0) {
- iYear = iYears > 0 ? 1 : -1;
- }
- m_iUnitime =
- FX_DateToDays(iYear, iMonth, iDay, FALSE) * g_FXMillisecondsPerDay;
- m_iUnitime += (iYear < 0) ? -r : r;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddMonths(int32_t iMonths) {
- FX_BOOL b = iMonths > 0;
- FX_UNITIME ut = m_iUnitime;
- if (ut < 0) {
- ut = -ut;
- }
- FX_UNITIME r = ut % g_FXMillisecondsPerDay;
- int32_t iYear;
- uint8_t iMonth, iDay;
- FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
- iMonths += iMonth;
- while (iMonths < 1) {
- iYear--, iMonths += 12;
- }
- while (iMonths > 12) {
- iYear++, iMonths -= 12;
- }
- if (iYear == 0) {
- iYear = b ? 1 : -1;
- }
- m_iUnitime = FX_DateToDays(iYear, (uint8_t)iMonths, iDay, FALSE) *
- g_FXMillisecondsPerDay;
- m_iUnitime += (iYear < 0) ? -r : r;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddDays(int32_t iDays) {
- m_iUnitime += (int64_t)iDays * g_FXMillisecondsPerDay;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddHours(int32_t iHours) {
- m_iUnitime += (int64_t)iHours * g_FXMillisecondsPerHour;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddMinutes(int32_t iMinutes) {
- m_iUnitime += (int64_t)iMinutes * g_FXMillisecondsPerMinute;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddSeconds(int32_t iSeconds) {
- m_iUnitime += ((int64_t)iSeconds) * g_FXMillisecondsPerSecond;
- return TRUE;
-}
-FX_BOOL CFX_Unitime::AddMilliseconds(int32_t iMilliseconds) {
- m_iUnitime += iMilliseconds;
- return TRUE;
-}
-FX_BOOL CFX_DateTime::Set(int32_t year,
- uint8_t month,
- uint8_t day,
- uint8_t hour,
- uint8_t minute,
- uint8_t second,
- FX_WORD millisecond) {
- ASSERT(year != 0);
- ASSERT(month >= 1 && month <= 12);
- ASSERT(day >= 1 && day <= FX_DaysInMonth(year, month));
- ASSERT(hour <= 23);
- ASSERT(minute <= 59);
- ASSERT(second <= 59);
- ASSERT(millisecond <= 999);
- m_DateTime.Date.sDate.year = year;
- m_DateTime.Date.sDate.month = month;
- m_DateTime.Date.sDate.day = day;
- m_DateTime.Time.sTime.hour = hour;
- m_DateTime.Time.sTime.minute = minute;
- m_DateTime.Time.sTime.second = second;
- m_DateTime.Time.sTime.millisecond = millisecond;
- return TRUE;
-}
-FX_BOOL CFX_DateTime::FromUnitime(FX_UNITIME t) {
- CFX_Unitime ut(t);
- FX_DaysToDate(ut.GetDayOfAD(), m_DateTime.Date.sDate.year,
- m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day);
- m_DateTime.Date.sDate.day = ut.GetHour();
- m_DateTime.Time.sTime.minute = ut.GetMinute();
- m_DateTime.Time.sTime.second = ut.GetSecond();
- m_DateTime.Time.sTime.millisecond = ut.GetMillisecond();
- return TRUE;
-}
-FX_UNITIME CFX_DateTime::ToUnitime() const {
- FX_UNITIME v =
- (int64_t)m_DateTime.Date.sDate.day * g_FXMillisecondsPerHour +
- (int64_t)m_DateTime.Time.sTime.minute * g_FXMillisecondsPerMinute +
- (int64_t)m_DateTime.Time.sTime.second * g_FXMillisecondsPerSecond +
- m_DateTime.Time.sTime.millisecond;
- v += FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
- m_DateTime.Date.sDate.day, FALSE) *
- g_FXMillisecondsPerDay;
- return v;
-}
-int32_t CFX_DateTime::GetYear() const {
- return m_DateTime.Date.sDate.year;
-}
-uint8_t CFX_DateTime::GetMonth() const {
- return m_DateTime.Date.sDate.month;
-}
-uint8_t CFX_DateTime::GetDay() const {
- return m_DateTime.Date.sDate.day;
-}
-FX_WEEKDAY CFX_DateTime::GetDayOfWeek() const {
- int32_t v = (int32_t)(FX_DateToDays(m_DateTime.Date.sDate.year,
- m_DateTime.Date.sDate.month,
- m_DateTime.Date.sDate.day, TRUE) %
- 7);
- if (v < 0) {
- v += 7;
- }
- return (FX_WEEKDAY)v;
-}
-FX_WORD CFX_DateTime::GetDayOfYear() const {
- return FX_DaysBeforeMonthInYear(m_DateTime.Date.sDate.year,
- m_DateTime.Date.sDate.month) +
- m_DateTime.Date.sDate.day;
-}
-int64_t CFX_DateTime::GetDayOfAD() const {
- return FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
- m_DateTime.Date.sDate.day, TRUE);
-}
-uint8_t CFX_DateTime::GetHour() const {
- return m_DateTime.Date.sDate.day;
-}
-uint8_t CFX_DateTime::GetMinute() const {
- return m_DateTime.Time.sTime.minute;
-}
-uint8_t CFX_DateTime::GetSecond() const {
- return m_DateTime.Time.sTime.second;
-}
-FX_WORD CFX_DateTime::GetMillisecond() const {
- return m_DateTime.Time.sTime.millisecond;
-}
-FX_BOOL CFX_DateTime::AddYears(int32_t iYears) {
- if (iYears == 0) {
- return FALSE;
- }
- int32_t v = m_DateTime.Date.sDate.year + iYears;
- if (v >= 0 && m_DateTime.Date.sDate.year < 0) {
- v++;
- } else if (v <= 0 && m_DateTime.Date.sDate.year > 0) {
- v--;
- }
- m_DateTime.Date.sDate.year = v;
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddMonths(int32_t iMonths) {
- if (iMonths == 0) {
- return FALSE;
- }
- FX_BOOL b = iMonths > 0;
- iMonths += m_DateTime.Date.sDate.month;
- while (iMonths < 1) {
- m_DateTime.Date.sDate.year--;
- if (m_DateTime.Date.sDate.year == 0) {
- m_DateTime.Date.sDate.year = -1;
- }
- iMonths += 12;
- }
- while (iMonths > 12) {
- m_DateTime.Date.sDate.year++;
- if (m_DateTime.Date.sDate.year == 0) {
- m_DateTime.Date.sDate.year = 1;
- }
- iMonths -= 12;
- }
- if (m_DateTime.Date.sDate.year == 0) {
- m_DateTime.Date.sDate.year = b ? 1 : -1;
- }
- m_DateTime.Date.sDate.month = (uint8_t)iMonths;
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddDays(int32_t iDays) {
- if (iDays == 0) {
- return FALSE;
- }
- int64_t v1 =
- FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
- m_DateTime.Date.sDate.day, TRUE);
- int64_t v2 = v1 + iDays;
- if (v2 <= 0 && v1 > 0) {
- v2--;
- } else if (v2 >= 0 && v1 < 0) {
- v2++;
- }
- FX_DaysToDate(v2, m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
- m_DateTime.Date.sDate.day);
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddHours(int32_t iHours) {
- if (iHours == 0) {
- return FALSE;
- }
- iHours += m_DateTime.Date.sDate.day;
- int32_t iDays = iHours / 24;
- iHours %= 24;
- if (iHours < 0) {
- iDays--, iHours += 24;
- }
- m_DateTime.Date.sDate.day = (uint8_t)iHours;
- if (iDays != 0) {
- AddDays(iDays);
- }
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddMinutes(int32_t iMinutes) {
- if (iMinutes == 0) {
- return FALSE;
- }
- iMinutes += m_DateTime.Time.sTime.minute;
- int32_t iHours = iMinutes / 60;
- iMinutes %= 60;
- if (iMinutes < 0) {
- iHours--, iMinutes += 60;
- }
- m_DateTime.Time.sTime.minute = (uint8_t)iMinutes;
- if (iHours != 0) {
- AddHours(iHours);
- }
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddSeconds(int32_t iSeconds) {
- if (iSeconds == 0) {
- return FALSE;
- }
- iSeconds += m_DateTime.Time.sTime.second;
- int32_t iMinutes = iSeconds / 60;
- iSeconds %= 60;
- if (iSeconds < 0) {
- iMinutes--, iSeconds += 60;
- }
- m_DateTime.Time.sTime.second = (uint8_t)iSeconds;
- if (iMinutes != 0) {
- AddMinutes(iMinutes);
- }
- return TRUE;
-}
-FX_BOOL CFX_DateTime::AddMilliseconds(int32_t iMilliseconds) {
- if (iMilliseconds == 0) {
- return FALSE;
- }
- iMilliseconds += m_DateTime.Time.sTime.millisecond;
- int32_t iSeconds = (int32_t)(iMilliseconds / g_FXMillisecondsPerSecond);
- iMilliseconds %= g_FXMillisecondsPerSecond;
- if (iMilliseconds < 0) {
- iSeconds--, iMilliseconds += g_FXMillisecondsPerSecond;
- }
- m_DateTime.Time.sTime.millisecond = (FX_WORD)iMilliseconds;
- if (iSeconds != 0) {
- AddSeconds(iSeconds);
- }
- return TRUE;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/src/fgas/src/fgas_base.h"
+const uint8_t g_FXDaysPerMonth[12] = {31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31};
+const uint8_t g_FXDaysPerLeapMonth[12] = {31, 29, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31};
+const int32_t g_FXDaysBeforeMonth[12] = {0, 31, 59, 90, 120, 151,
+ 181, 212, 243, 273, 304, 334};
+const int32_t g_FXDaysBeforeLeapMonth[12] = {0, 31, 60, 91, 121, 152,
+ 182, 213, 244, 274, 305, 335};
+const int32_t g_FXDaysPerYear = 365;
+const int32_t g_FXDaysPerLeapYear = 366;
+const int32_t g_FXDaysPer4Years = 1461;
+const int32_t g_FXDaysPer100Years = 36524;
+const int32_t g_FXDaysPer400Years = 146097;
+const int64_t g_FXMillisecondsPerSecond = 1000;
+const int64_t g_FXMillisecondsPerMinute = 60000;
+const int64_t g_FXMillisecondsPerHour = 3600000;
+const int64_t g_FXMillisecondsPerDay = 86400000;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+const int64_t g_FXMillisecondsPerYear = 0x0757B12C00;
+const int64_t g_FXMillisecondsPerLeapYear = 0x075CD78800;
+const int64_t g_FXMillisecondsPer4Years = 0x1D63EB0C00;
+const int64_t g_FXMillisecondsPer100Years = 0x02DEBCCDD000;
+const int64_t g_FXMillisecondsPer400Years = 0x0B7AF85D9C00;
+#endif
+FX_BOOL FX_IsLeapYear(int32_t iYear) {
+ FXSYS_assert(iYear != 0);
+ return ((iYear % 4) == 0 && (iYear % 100) != 0) || (iYear % 400) == 0;
+}
+int32_t FX_DaysInYear(int32_t iYear) {
+ FXSYS_assert(iYear != 0);
+ return FX_IsLeapYear(iYear) ? g_FXDaysPerLeapYear : g_FXDaysPerYear;
+}
+uint8_t FX_DaysInMonth(int32_t iYear, uint8_t iMonth) {
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ const uint8_t* p =
+ FX_IsLeapYear(iYear) ? g_FXDaysPerLeapMonth : g_FXDaysPerMonth;
+ return p[iMonth - 1];
+}
+static int32_t FX_DaysBeforeMonthInYear(int32_t iYear, uint8_t iMonth) {
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ const int32_t* p =
+ FX_IsLeapYear(iYear) ? g_FXDaysBeforeLeapMonth : g_FXDaysBeforeMonth;
+ return p[iMonth - 1];
+}
+static int64_t FX_DateToDays(int32_t iYear,
+ uint8_t iMonth,
+ uint8_t iDay,
+ FX_BOOL bIncludeThisDay = FALSE) {
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ FXSYS_assert(iDay >= 1 && iDay <= FX_DaysInMonth(iYear, iMonth));
+ int64_t iDays = FX_DaysBeforeMonthInYear(iYear, iMonth);
+ iDays += iDay;
+ if (!bIncludeThisDay) {
+ iDays--;
+ }
+ if (iYear > 0) {
+ iYear--;
+ } else {
+ iDays -= FX_DaysInYear(iYear);
+ iYear++;
+ }
+ return iDays + (int64_t)iYear * 365 + iYear / 4 - iYear / 100 + iYear / 400;
+}
+static void FX_DaysToDate(int64_t iDays,
+ int32_t& iYear,
+ uint8_t& iMonth,
+ uint8_t& iDay) {
+ FX_BOOL bBC = iDays < 0;
+ if (bBC) {
+ iDays = -iDays;
+ }
+ iYear = 1;
+ iMonth = 1;
+ iDay = 1;
+ if (iDays >= g_FXDaysPer400Years) {
+ iYear += (int32_t)(iDays / g_FXDaysPer400Years * 400);
+ iDays %= g_FXDaysPer400Years;
+ }
+ if (iDays >= g_FXDaysPer100Years) {
+ if (iDays == g_FXDaysPer100Years * 4) {
+ iYear += 300;
+ iDays -= g_FXDaysPer100Years * 3;
+ } else {
+ iYear += (int32_t)(iDays / g_FXDaysPer100Years * 100);
+ iDays %= g_FXDaysPer100Years;
+ }
+ }
+ if (iDays >= g_FXDaysPer4Years) {
+ iYear += (int32_t)(iDays / g_FXDaysPer4Years * 4);
+ iDays %= g_FXDaysPer4Years;
+ }
+ while (TRUE) {
+ int32_t iYearDays = FX_DaysInYear(iYear);
+ if (iDays < iYearDays) {
+ if (bBC) {
+ iYear = -iYear;
+ iDays = iYearDays - iDays;
+ }
+ break;
+ }
+ iYear++;
+ iDays -= iYearDays;
+ }
+ while (TRUE) {
+ int32_t iMonthDays = FX_DaysInMonth(iYear, iMonth);
+ if (iDays < iMonthDays) {
+ break;
+ }
+ iMonth++;
+ iDays -= iMonthDays;
+ }
+ iDay += (uint8_t)iDays;
+}
+#if _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_ || \
+ _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
+#include <time.h>
+#include <sys/time.h>
+#endif
+typedef struct _FXUT_SYSTEMTIME {
+ FX_WORD wYear;
+ FX_WORD wMonth;
+ FX_WORD wDayOfWeek;
+ FX_WORD wDay;
+ FX_WORD wHour;
+ FX_WORD wMinute;
+ FX_WORD wSecond;
+ FX_WORD wMilliseconds;
+} FXUT_SYSTEMTIME;
+void CFX_Unitime::Now() {
+ FXUT_SYSTEMTIME utLocal;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+ ::GetLocalTime((LPSYSTEMTIME)&utLocal);
+#elif _FX_OS_ != _FX_EMBEDDED_
+#if 1
+ timeval curTime;
+ gettimeofday(&curTime, NULL);
+#else
+ struct timespec curTime;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
+#endif
+ struct tm st;
+ localtime_r(&curTime.tv_sec, &st);
+ utLocal.wYear = st.tm_year + 1900;
+ utLocal.wMonth = st.tm_mon + 1;
+ utLocal.wDayOfWeek = st.tm_wday;
+ utLocal.wDay = st.tm_mday;
+ utLocal.wHour = st.tm_hour;
+ utLocal.wMinute = st.tm_min;
+ utLocal.wSecond = st.tm_sec;
+ utLocal.wMilliseconds = curTime.tv_usec / 1000;
+#endif
+ Set(utLocal.wYear, (uint8_t)utLocal.wMonth, (uint8_t)utLocal.wDay,
+ (uint8_t)utLocal.wHour, (uint8_t)utLocal.wMinute,
+ (uint8_t)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
+}
+void CFX_Unitime::SetGMTime() {
+ FXUT_SYSTEMTIME utLocal;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
+ _FX_OS_ == _FX_WIN64_
+ ::GetSystemTime((LPSYSTEMTIME)&utLocal);
+#elif _FX_OS_ != _FX_EMBEDDED_
+#if 1
+ timeval curTime;
+ gettimeofday(&curTime, NULL);
+#else
+ struct timespec curTime;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
+#endif
+ struct tm st;
+ gmtime_r(&curTime.tv_sec, &st);
+ utLocal.wYear = st.tm_year + 1900;
+ utLocal.wMonth = st.tm_mon + 1;
+ utLocal.wDayOfWeek = st.tm_wday;
+ utLocal.wDay = st.tm_mday;
+ utLocal.wHour = st.tm_hour;
+ utLocal.wMinute = st.tm_min;
+ utLocal.wSecond = st.tm_sec;
+ utLocal.wMilliseconds = curTime.tv_usec / 1000;
+#endif
+ Set(utLocal.wYear, (uint8_t)utLocal.wMonth, (uint8_t)utLocal.wDay,
+ (uint8_t)utLocal.wHour, (uint8_t)utLocal.wMinute,
+ (uint8_t)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
+}
+void CFX_Unitime::Set(int32_t year,
+ uint8_t month,
+ uint8_t day,
+ uint8_t hour,
+ uint8_t minute,
+ uint8_t second,
+ FX_WORD millisecond) {
+ FXSYS_assert(hour <= 23);
+ FXSYS_assert(minute <= 59);
+ FXSYS_assert(second <= 59);
+ FXSYS_assert(millisecond <= 999);
+ m_iUnitime = (int64_t)hour * g_FXMillisecondsPerHour +
+ (int64_t)minute * g_FXMillisecondsPerMinute +
+ (int64_t)second * g_FXMillisecondsPerSecond + millisecond;
+ if (year > 0) {
+ m_iUnitime =
+ m_iUnitime +
+ FX_DateToDays(year, month, day, FALSE) * g_FXMillisecondsPerDay;
+ }
+}
+void CFX_Unitime::Set(FX_UNITIME t) {
+ m_iUnitime = t;
+}
+int32_t CFX_Unitime::GetYear() const {
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iYear;
+}
+uint8_t CFX_Unitime::GetMonth() const {
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iMonth;
+}
+uint8_t CFX_Unitime::GetDay() const {
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iDay;
+}
+FX_WEEKDAY CFX_Unitime::GetDayOfWeek() const {
+ int32_t v = (int32_t)((m_iUnitime / g_FXMillisecondsPerDay + 1) % 7);
+ if (v < 0) {
+ v += 7;
+ }
+ return (FX_WEEKDAY)v;
+}
+FX_WORD CFX_Unitime::GetDayOfYear() const {
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return FX_DaysBeforeMonthInYear(iYear, iMonth) + iDay;
+}
+int64_t CFX_Unitime::GetDayOfAD() const {
+ FX_BOOL bBC = m_iUnitime < 0;
+ int64_t iDays = m_iUnitime / g_FXMillisecondsPerDay;
+ iDays += bBC ? -1 : 0;
+ if (bBC && (m_iUnitime % g_FXMillisecondsPerDay) == 0) {
+ iDays++;
+ }
+ return iDays;
+}
+uint8_t CFX_Unitime::GetHour() const {
+ int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerDay);
+ if (v < 0) {
+ v += g_FXMillisecondsPerDay;
+ }
+ return (uint8_t)(v / g_FXMillisecondsPerHour);
+}
+uint8_t CFX_Unitime::GetMinute() const {
+ int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerHour);
+ if (v < 0) {
+ v += g_FXMillisecondsPerHour;
+ }
+ return (uint8_t)(v / g_FXMillisecondsPerMinute);
+}
+uint8_t CFX_Unitime::GetSecond() const {
+ int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerMinute);
+ if (v < 0) {
+ v += g_FXMillisecondsPerMinute;
+ }
+ return (uint8_t)(v / g_FXMillisecondsPerSecond);
+}
+FX_WORD CFX_Unitime::GetMillisecond() const {
+ int32_t v = (int32_t)(m_iUnitime % g_FXMillisecondsPerSecond);
+ if (v < 0) {
+ v += g_FXMillisecondsPerSecond;
+ }
+ return (FX_WORD)v;
+}
+FX_BOOL CFX_Unitime::AddYears(int32_t iYears) {
+ FX_UNITIME ut = m_iUnitime;
+ if (ut < 0) {
+ ut = -ut;
+ }
+ FX_UNITIME r = ut % g_FXMillisecondsPerDay;
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ iYear += iYears;
+ if (iYear == 0) {
+ iYear = iYears > 0 ? 1 : -1;
+ }
+ m_iUnitime =
+ FX_DateToDays(iYear, iMonth, iDay, FALSE) * g_FXMillisecondsPerDay;
+ m_iUnitime += (iYear < 0) ? -r : r;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMonths(int32_t iMonths) {
+ FX_BOOL b = iMonths > 0;
+ FX_UNITIME ut = m_iUnitime;
+ if (ut < 0) {
+ ut = -ut;
+ }
+ FX_UNITIME r = ut % g_FXMillisecondsPerDay;
+ int32_t iYear;
+ uint8_t iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ iMonths += iMonth;
+ while (iMonths < 1) {
+ iYear--, iMonths += 12;
+ }
+ while (iMonths > 12) {
+ iYear++, iMonths -= 12;
+ }
+ if (iYear == 0) {
+ iYear = b ? 1 : -1;
+ }
+ m_iUnitime = FX_DateToDays(iYear, (uint8_t)iMonths, iDay, FALSE) *
+ g_FXMillisecondsPerDay;
+ m_iUnitime += (iYear < 0) ? -r : r;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddDays(int32_t iDays) {
+ m_iUnitime += (int64_t)iDays * g_FXMillisecondsPerDay;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddHours(int32_t iHours) {
+ m_iUnitime += (int64_t)iHours * g_FXMillisecondsPerHour;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMinutes(int32_t iMinutes) {
+ m_iUnitime += (int64_t)iMinutes * g_FXMillisecondsPerMinute;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddSeconds(int32_t iSeconds) {
+ m_iUnitime += ((int64_t)iSeconds) * g_FXMillisecondsPerSecond;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMilliseconds(int32_t iMilliseconds) {
+ m_iUnitime += iMilliseconds;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::Set(int32_t year,
+ uint8_t month,
+ uint8_t day,
+ uint8_t hour,
+ uint8_t minute,
+ uint8_t second,
+ FX_WORD millisecond) {
+ ASSERT(year != 0);
+ ASSERT(month >= 1 && month <= 12);
+ ASSERT(day >= 1 && day <= FX_DaysInMonth(year, month));
+ ASSERT(hour <= 23);
+ ASSERT(minute <= 59);
+ ASSERT(second <= 59);
+ ASSERT(millisecond <= 999);
+ m_DateTime.Date.sDate.year = year;
+ m_DateTime.Date.sDate.month = month;
+ m_DateTime.Date.sDate.day = day;
+ m_DateTime.Time.sTime.hour = hour;
+ m_DateTime.Time.sTime.minute = minute;
+ m_DateTime.Time.sTime.second = second;
+ m_DateTime.Time.sTime.millisecond = millisecond;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::FromUnitime(FX_UNITIME t) {
+ CFX_Unitime ut(t);
+ FX_DaysToDate(ut.GetDayOfAD(), m_DateTime.Date.sDate.year,
+ m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day);
+ m_DateTime.Date.sDate.day = ut.GetHour();
+ m_DateTime.Time.sTime.minute = ut.GetMinute();
+ m_DateTime.Time.sTime.second = ut.GetSecond();
+ m_DateTime.Time.sTime.millisecond = ut.GetMillisecond();
+ return TRUE;
+}
+FX_UNITIME CFX_DateTime::ToUnitime() const {
+ FX_UNITIME v =
+ (int64_t)m_DateTime.Date.sDate.day * g_FXMillisecondsPerHour +
+ (int64_t)m_DateTime.Time.sTime.minute * g_FXMillisecondsPerMinute +
+ (int64_t)m_DateTime.Time.sTime.second * g_FXMillisecondsPerSecond +
+ m_DateTime.Time.sTime.millisecond;
+ v += FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
+ m_DateTime.Date.sDate.day, FALSE) *
+ g_FXMillisecondsPerDay;
+ return v;
+}
+int32_t CFX_DateTime::GetYear() const {
+ return m_DateTime.Date.sDate.year;
+}
+uint8_t CFX_DateTime::GetMonth() const {
+ return m_DateTime.Date.sDate.month;
+}
+uint8_t CFX_DateTime::GetDay() const {
+ return m_DateTime.Date.sDate.day;
+}
+FX_WEEKDAY CFX_DateTime::GetDayOfWeek() const {
+ int32_t v = (int32_t)(FX_DateToDays(m_DateTime.Date.sDate.year,
+ m_DateTime.Date.sDate.month,
+ m_DateTime.Date.sDate.day, TRUE) %
+ 7);
+ if (v < 0) {
+ v += 7;
+ }
+ return (FX_WEEKDAY)v;
+}
+FX_WORD CFX_DateTime::GetDayOfYear() const {
+ return FX_DaysBeforeMonthInYear(m_DateTime.Date.sDate.year,
+ m_DateTime.Date.sDate.month) +
+ m_DateTime.Date.sDate.day;
+}
+int64_t CFX_DateTime::GetDayOfAD() const {
+ return FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
+ m_DateTime.Date.sDate.day, TRUE);
+}
+uint8_t CFX_DateTime::GetHour() const {
+ return m_DateTime.Date.sDate.day;
+}
+uint8_t CFX_DateTime::GetMinute() const {
+ return m_DateTime.Time.sTime.minute;
+}
+uint8_t CFX_DateTime::GetSecond() const {
+ return m_DateTime.Time.sTime.second;
+}
+FX_WORD CFX_DateTime::GetMillisecond() const {
+ return m_DateTime.Time.sTime.millisecond;
+}
+FX_BOOL CFX_DateTime::AddYears(int32_t iYears) {
+ if (iYears == 0) {
+ return FALSE;
+ }
+ int32_t v = m_DateTime.Date.sDate.year + iYears;
+ if (v >= 0 && m_DateTime.Date.sDate.year < 0) {
+ v++;
+ } else if (v <= 0 && m_DateTime.Date.sDate.year > 0) {
+ v--;
+ }
+ m_DateTime.Date.sDate.year = v;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMonths(int32_t iMonths) {
+ if (iMonths == 0) {
+ return FALSE;
+ }
+ FX_BOOL b = iMonths > 0;
+ iMonths += m_DateTime.Date.sDate.month;
+ while (iMonths < 1) {
+ m_DateTime.Date.sDate.year--;
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = -1;
+ }
+ iMonths += 12;
+ }
+ while (iMonths > 12) {
+ m_DateTime.Date.sDate.year++;
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = 1;
+ }
+ iMonths -= 12;
+ }
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = b ? 1 : -1;
+ }
+ m_DateTime.Date.sDate.month = (uint8_t)iMonths;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddDays(int32_t iDays) {
+ if (iDays == 0) {
+ return FALSE;
+ }
+ int64_t v1 =
+ FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
+ m_DateTime.Date.sDate.day, TRUE);
+ int64_t v2 = v1 + iDays;
+ if (v2 <= 0 && v1 > 0) {
+ v2--;
+ } else if (v2 >= 0 && v1 < 0) {
+ v2++;
+ }
+ FX_DaysToDate(v2, m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month,
+ m_DateTime.Date.sDate.day);
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddHours(int32_t iHours) {
+ if (iHours == 0) {
+ return FALSE;
+ }
+ iHours += m_DateTime.Date.sDate.day;
+ int32_t iDays = iHours / 24;
+ iHours %= 24;
+ if (iHours < 0) {
+ iDays--, iHours += 24;
+ }
+ m_DateTime.Date.sDate.day = (uint8_t)iHours;
+ if (iDays != 0) {
+ AddDays(iDays);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMinutes(int32_t iMinutes) {
+ if (iMinutes == 0) {
+ return FALSE;
+ }
+ iMinutes += m_DateTime.Time.sTime.minute;
+ int32_t iHours = iMinutes / 60;
+ iMinutes %= 60;
+ if (iMinutes < 0) {
+ iHours--, iMinutes += 60;
+ }
+ m_DateTime.Time.sTime.minute = (uint8_t)iMinutes;
+ if (iHours != 0) {
+ AddHours(iHours);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddSeconds(int32_t iSeconds) {
+ if (iSeconds == 0) {
+ return FALSE;
+ }
+ iSeconds += m_DateTime.Time.sTime.second;
+ int32_t iMinutes = iSeconds / 60;
+ iSeconds %= 60;
+ if (iSeconds < 0) {
+ iMinutes--, iSeconds += 60;
+ }
+ m_DateTime.Time.sTime.second = (uint8_t)iSeconds;
+ if (iMinutes != 0) {
+ AddMinutes(iMinutes);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMilliseconds(int32_t iMilliseconds) {
+ if (iMilliseconds == 0) {
+ return FALSE;
+ }
+ iMilliseconds += m_DateTime.Time.sTime.millisecond;
+ int32_t iSeconds = (int32_t)(iMilliseconds / g_FXMillisecondsPerSecond);
+ iMilliseconds %= g_FXMillisecondsPerSecond;
+ if (iMilliseconds < 0) {
+ iSeconds--, iMilliseconds += g_FXMillisecondsPerSecond;
+ }
+ m_DateTime.Time.sTime.millisecond = (FX_WORD)iMilliseconds;
+ if (iSeconds != 0) {
+ AddSeconds(iSeconds);
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fgas/src/localization/fx_locale.cpp b/xfa/src/fgas/src/localization/fx_locale.cpp
index 49629101c9..4b69a5bbed 100644
--- a/xfa/src/fgas/src/localization/fx_locale.cpp
+++ b/xfa/src/fgas/src/localization/fx_locale.cpp
@@ -1,5127 +1,5127 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "core/include/fxcrt/fx_xml.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_localeimp.h"
-
-#define FX_LOCALECATEGORY_DateHash 0xbde9abde
-#define FX_LOCALECATEGORY_TimeHash 0x2d71b00f
-#define FX_LOCALECATEGORY_DateTimeHash 0x158c72ed
-#define FX_LOCALECATEGORY_NumHash 0x0b4ff870
-#define FX_LOCALECATEGORY_TextHash 0x2d08af85
-#define FX_LOCALECATEGORY_ZeroHash 0x568cb500
-#define FX_LOCALECATEGORY_NullHash 0x052931bb
-typedef struct _FX_LOCALESUBCATEGORYINFO {
- uint32_t uHash;
- const FX_WCHAR* pName;
- int32_t eSubCategory;
-} FX_LOCALESUBCATEGORYINFO, *FX_LPLOCALESUBCATEGORYINFO;
-typedef FX_LOCALESUBCATEGORYINFO const* FX_LPCLOCALESUBCATEGORYINFO;
-const static FX_LOCALESUBCATEGORYINFO g_FXLocaleDateTimeSubCatData[] = {
- {0x14da2125, L"default", FX_LOCALEDATETIMESUBCATEGORY_Default},
- {0x9041d4b0, L"short", FX_LOCALEDATETIMESUBCATEGORY_Short},
- {0xa084a381, L"medium", FX_LOCALEDATETIMESUBCATEGORY_Medium},
- {0xcdce56b3, L"full", FX_LOCALEDATETIMESUBCATEGORY_Full},
- {0xf6b4afb0, L"long", FX_LOCALEDATETIMESUBCATEGORY_Long},
-};
-const static int32_t g_iFXLocaleDateTimeSubCatCount =
- sizeof(g_FXLocaleDateTimeSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
-const static FX_LOCALESUBCATEGORYINFO g_FXLocaleNumSubCatData[] = {
- {0x46f95531, L"percent", FX_LOCALENUMPATTERN_Percent},
- {0x4c4e8acb, L"currency", FX_LOCALENUMPATTERN_Currency},
- {0x54034c2f, L"decimal", FX_LOCALENUMPATTERN_Decimal},
- {0x7568e6ae, L"integer", FX_LOCALENUMPATTERN_Integer},
-};
-const static int32_t g_iFXLocaleNumSubCatCount =
- sizeof(g_FXLocaleNumSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
-typedef struct _FX_LOCALETIMEZONEINFO {
- FX_DWORD uHash;
- int16_t iHour;
- int16_t iMinute;
-} FX_LOCALETIMEZONEINFO, *FX_LPLOCALETIMEZONEINFO;
-typedef FX_LOCALETIMEZONEINFO const* FX_LPCLOCALETIMEZONEINFO;
-const static FX_LOCALETIMEZONEINFO g_FXLocaleTimeZoneData[] = {
- {FXBSTR_ID(0, 'C', 'D', 'T'), -5, 0}, {FXBSTR_ID(0, 'C', 'S', 'T'), -6, 0},
- {FXBSTR_ID(0, 'E', 'D', 'T'), -4, 0}, {FXBSTR_ID(0, 'E', 'S', 'T'), -5, 0},
- {FXBSTR_ID(0, 'M', 'D', 'T'), -6, 0}, {FXBSTR_ID(0, 'M', 'S', 'T'), -7, 0},
- {FXBSTR_ID(0, 'P', 'D', 'T'), -7, 0}, {FXBSTR_ID(0, 'P', 'S', 'T'), -8, 0},
-};
-const static int32_t g_iFXLocaleTimeZoneCount =
- sizeof(g_FXLocaleTimeZoneData) / sizeof(FX_LOCALETIMEZONEINFO);
-const static CFX_WideStringC gs_wsTextSymbols = FX_WSTRC(L"AXO09");
-const static CFX_WideStringC gs_wsTimeSymbols = FX_WSTRC(L"hHkKMSFAzZ");
-const static CFX_WideStringC gs_wsDateSymbols = FX_WSTRC(L"DJMEeGgYwW");
-const static CFX_WideStringC gs_wsConstChars = FX_WSTRC(L",-:/. ");
-static FX_STRSIZE FX_Local_Find(const CFX_WideStringC& wsSymbols,
- FX_WCHAR ch,
- FX_STRSIZE nStart = 0) {
- FX_STRSIZE nLength = wsSymbols.GetLength();
- if (nLength < 1 || nStart > nLength) {
- return -1;
- }
- const FX_WCHAR* lpsz =
- (const FX_WCHAR*)FXSYS_wcschr(wsSymbols.GetPtr() + nStart, ch);
- return (lpsz == NULL) ? -1 : (FX_STRSIZE)(lpsz - wsSymbols.GetPtr());
-}
-static const FX_WCHAR* const gs_LocalNumberSymbols[] = {
- L"decimal", L"grouping", L"percent", L"minus",
- L"zero", L"currencySymbol", L"currencyName",
-};
-IFX_Locale* IFX_Locale::Create(CXML_Element* pLocaleData) {
- return new CFX_Locale(pLocaleData);
-}
-CFX_Locale::CFX_Locale(CXML_Element* pLocaleData) {
- m_pElement = pLocaleData;
-}
-CFX_Locale::~CFX_Locale() {}
-CFX_WideString CFX_Locale::GetName() {
- return CFX_WideString();
-}
-static CFX_WideString FX_GetXMLContent(const CFX_ByteStringC& bsSpace,
- CXML_Element* pxmlElement,
- const CFX_ByteStringC& bsTag,
- const CFX_WideStringC& wsName) {
- CXML_Element* pDatePattern = NULL;
- int32_t nCount = pxmlElement->CountElements(bsSpace, bsTag);
- int32_t i = 0;
- for (; i < nCount; i++) {
- pDatePattern = pxmlElement->GetElement(bsSpace, bsTag, i);
- if (pDatePattern->GetAttrValue("name") == wsName) {
- break;
- }
- }
- if (i < nCount && pDatePattern) {
- return pDatePattern->GetContent(0);
- }
- return L"";
-}
-void CFX_Locale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
- CFX_WideString& wsNumSymbol) const {
- if (!m_pElement) {
- return;
- }
- CFX_ByteString bsSpace;
- CFX_WideString wsName = gs_LocalNumberSymbols[eType];
- CXML_Element* pNumberSymbols =
- m_pElement->GetElement(bsSpace, "numberSymbols");
- if (!pNumberSymbols) {
- return;
- }
- wsNumSymbol =
- FX_GetXMLContent(bsSpace, pNumberSymbols, "numberSymbol", wsName);
-}
-void CFX_Locale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const {
- if (!m_pElement) {
- return;
- }
- CFX_ByteString bsSpace;
- CXML_Element* pNumberSymbols =
- m_pElement->GetElement(bsSpace, "dateTimeSymbols");
- if (!pNumberSymbols) {
- return;
- }
- wsDtSymbol = pNumberSymbols->GetContent(0);
-}
-static void FX_GetCalendarSymbol(CXML_Element* pXmlElement,
- const CFX_ByteString& symbol_type,
- int32_t index,
- FX_BOOL bAbbr,
- CFX_WideString& wsName) {
- CFX_ByteString bsSpace;
- CFX_ByteString pstrSymbolNames = symbol_type + "Names";
- CXML_Element* pChild = pXmlElement->GetElement(bsSpace, "calendarSymbols");
- if (!pChild) {
- return;
- }
- CXML_Element* pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames);
- if (!pSymbolNames) {
- return;
- }
- if (pSymbolNames->GetAttrInteger("abbr") != bAbbr) {
- pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames, 1);
- }
- if (pSymbolNames && pSymbolNames->GetAttrInteger("abbr") == bAbbr) {
- CXML_Element* pSymbolName =
- pSymbolNames->GetElement(bsSpace, symbol_type, index);
- if (pSymbolName) {
- wsName = pSymbolName->GetContent(0);
- }
- }
-}
-void CFX_Locale::GetMonthName(int32_t nMonth,
- CFX_WideString& wsMonthName,
- FX_BOOL bAbbr) const {
- if (!m_pElement) {
- return;
- }
- FX_GetCalendarSymbol(m_pElement, "month", nMonth, bAbbr, wsMonthName);
-}
-void CFX_Locale::GetDayName(int32_t nWeek,
- CFX_WideString& wsDayName,
- FX_BOOL bAbbr) const {
- if (!m_pElement) {
- return;
- }
- FX_GetCalendarSymbol(m_pElement, "day", nWeek, bAbbr, wsDayName);
-}
-void CFX_Locale::GetMeridiemName(CFX_WideString& wsMeridiemName,
- FX_BOOL bAM) const {
- if (!m_pElement) {
- return;
- }
- FX_GetCalendarSymbol(m_pElement, "meridiem", bAM ? 0 : 1, FALSE,
- wsMeridiemName);
-}
-static int32_t FX_ParseTimeZone(const FX_WCHAR* pStr,
- int32_t iLen,
- FX_TIMEZONE& tz) {
- tz.tzHour = 0;
- tz.tzMinute = 0;
- if (iLen < 0) {
- return 0;
- }
- int32_t iStart = 1;
- int32_t iEnd = iStart + 2;
- while (iStart < iLen && iStart < iEnd) {
- tz.tzHour = tz.tzHour * 10 + pStr[iStart++] - '0';
- }
- if (iStart < iLen && pStr[iStart] == ':') {
- iStart++;
- }
- iEnd = iStart + 2;
- while (iStart < iLen && iStart < iEnd) {
- tz.tzMinute = tz.tzMinute * 10 + pStr[iStart++] - '0';
- }
- if (pStr[0] == '-') {
- tz.tzHour = -tz.tzHour;
- }
- return iStart;
-}
-void CFX_Locale::GetTimeZone(FX_TIMEZONE& tz) const {
- tz.tzHour = 0;
- tz.tzMinute = 0;
- if (!m_pElement) {
- return;
- }
- CXML_Element* pxmlTimeZone = m_pElement->GetElement("", "timeZone");
- if (pxmlTimeZone) {
- CFX_WideString wsTimeZone = pxmlTimeZone->GetContent(0);
- FX_ParseTimeZone(wsTimeZone, wsTimeZone.GetLength(), tz);
- }
-}
-void CFX_Locale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const {
- if (!m_pElement) {
- return;
- }
- FX_GetCalendarSymbol(m_pElement, "era", bAD ? 0 : 1, FALSE, wsEraName);
-}
-static void FX_GetPattern(CXML_Element* pXmlElement,
- const CFX_ByteString& bsCategory,
- const CFX_WideString& wsSubCategory,
- CFX_WideString& wsPattern) {
- CFX_ByteString bsSpace;
- CXML_Element* pDatePatterns =
- pXmlElement->GetElement(bsSpace, bsCategory + "s");
- if (!pDatePatterns) {
- return;
- }
- wsPattern =
- FX_GetXMLContent(bsSpace, pDatePatterns, bsCategory, wsSubCategory);
-}
-static void FX_GetDateTimePattern(CXML_Element* pXmlElement,
- const CFX_ByteString& bsCategory,
- FX_LOCALEDATETIMESUBCATEGORY eType,
- CFX_WideString& wsPattern) {
- CFX_WideString wsType = g_FXLocaleDateTimeSubCatData[eType].pName;
- FX_GetPattern(pXmlElement, bsCategory, wsType, wsPattern);
-}
-void CFX_Locale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
- CFX_WideString& wsPattern) const {
- if (!m_pElement) {
- return;
- }
- FX_GetDateTimePattern(m_pElement, "datePattern", eType, wsPattern);
-}
-void CFX_Locale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
- CFX_WideString& wsPattern) const {
- if (!m_pElement) {
- return;
- }
- FX_GetDateTimePattern(m_pElement, "timePattern", eType, wsPattern);
-}
-void CFX_Locale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
- CFX_WideString& wsPattern) const {
- CFX_WideString wsType = g_FXLocaleNumSubCatData[eType].pName;
- FX_GetPattern(m_pElement, "numberPattern", wsType, wsPattern);
-}
-static FX_BOOL FX_IsDigit(FX_WCHAR c) {
- return c >= '0' && c <= '9';
-}
-static FX_BOOL FX_IsAlpha(FX_WCHAR c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-}
-static FX_BOOL FX_IsSpace(FX_WCHAR c) {
- return (c == 0x20) || (c == 0x0d) || (c == 0x0a) || (c == 0x09);
-}
-static const FX_FLOAT gs_fraction_scales[] = {
- 0.1f, 0.01f, 0.001f, 0.0001f,
- 0.00001f, 0.000001f, 0.0000001f, 0.00000001f,
- 0.000000001f, 0.0000000001f, 0.00000000001f};
-static const int32_t gs_fraction_count =
- sizeof(gs_fraction_scales) / sizeof(FX_FLOAT);
-class CFX_LCNumeric {
- public:
- CFX_LCNumeric();
- CFX_LCNumeric(int64_t integral,
- FX_DWORD fractional = 0,
- int32_t exponent = 0);
- CFX_LCNumeric(FX_FLOAT dbRetValue);
- CFX_LCNumeric(double dbvalue);
- CFX_LCNumeric(CFX_WideString& wsNumeric);
-
- FX_FLOAT GetFloat() const;
- double GetDouble() const;
- CFX_WideString ToString() const;
- CFX_WideString ToString(int32_t nTreading, FX_BOOL bTrimTailZeros) const;
- int64_t m_Integral;
- FX_DWORD m_Fractional;
-#ifdef FX_NUM_DOUBLE
- CFX_WideString m_wsValue;
-#endif
- int32_t m_Exponent;
-};
-static FX_BOOL FX_WStringToNumeric(const CFX_WideString& wsValue,
- CFX_LCNumeric& lcnum) {
- int64_t* pIntegral = &lcnum.m_Integral;
- FX_DWORD* pFractional = &lcnum.m_Fractional;
- int32_t* pExponent = &lcnum.m_Exponent;
- *pIntegral = 0;
- *pFractional = 0;
- *pExponent = 0;
-#ifdef FX_NUM_DOUBLE
- lcnum.m_wsValue.Empty();
-#endif
- if (wsValue.IsEmpty()) {
- return FALSE;
- }
- const int32_t nIntegralMaxLen = 17;
- int32_t cc = 0;
- FX_BOOL bNegative = FALSE, bExpSign = FALSE;
- const FX_WCHAR* str = (const FX_WCHAR*)wsValue;
- int32_t len = wsValue.GetLength();
- while (cc < len && FX_IsSpace(str[cc])) {
- cc++;
- }
- if (cc >= len) {
- return FALSE;
- }
- if (str[cc] == '+') {
- cc++;
- } else if (str[cc] == '-') {
- bNegative = TRUE;
- cc++;
- }
- int32_t nIntegralLen = 0;
- while (cc < len) {
- if (str[cc] == '.') {
- break;
- }
- if (!FX_IsDigit(str[cc])) {
- if ((str[cc] == 'E' || str[cc] == 'e')) {
- break;
- } else {
- return FALSE;
- }
- }
- if (nIntegralLen < nIntegralMaxLen) {
- *pIntegral = *pIntegral * 10 + str[cc] - '0';
- nIntegralLen++;
- }
- cc++;
- }
- *pIntegral = bNegative ? -*pIntegral : *pIntegral;
- if (cc < len && str[cc] == '.') {
- int scale = 0;
- double fraction = 0.0;
- cc++;
- while (cc < len) {
- if (scale >= gs_fraction_count) {
- while (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- break;
- }
- cc++;
- }
- }
- if (!FX_IsDigit(str[cc])) {
- if ((str[cc] == 'E' || str[cc] == 'e')) {
- break;
- } else {
- return FALSE;
- }
- }
- fraction += gs_fraction_scales[scale] * (str[cc] - '0');
- scale++;
- cc++;
- }
- *pFractional = (FX_DWORD)(fraction * 4294967296.0);
- }
- if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
- cc++;
- if (cc < len) {
- if (str[cc] == '+') {
- cc++;
- } else if (str[cc] == '-') {
- bExpSign = TRUE;
- cc++;
- }
- }
- while (cc < len) {
- if (FX_IsDigit(str[cc])) {
- return FALSE;
- }
- *pExponent = *pExponent * 10 + str[cc] - '0';
- cc++;
- }
- *pExponent = bExpSign ? -*pExponent : *pExponent;
- }
-#ifdef FX_NUM_DOUBLE
- else {
- lcnum.m_wsValue = wsValue;
- }
-#endif
- return TRUE;
-}
-CFX_LCNumeric::CFX_LCNumeric() {
- m_Integral = 0;
- m_Fractional = 0;
- m_Exponent = 0;
-}
-CFX_LCNumeric::CFX_LCNumeric(int64_t integral,
- FX_DWORD fractional,
- int32_t exponent) {
- m_Integral = integral;
- m_Fractional = fractional;
- m_Exponent = exponent;
-}
-CFX_LCNumeric::CFX_LCNumeric(FX_FLOAT dbRetValue) {
- m_Integral = (int64_t)dbRetValue;
- m_Fractional = (FX_DWORD)(((dbRetValue > 0) ? (dbRetValue - m_Integral)
- : (m_Integral - dbRetValue)) *
- 4294967296);
- m_Exponent = 0;
-}
-CFX_LCNumeric::CFX_LCNumeric(double dbvalue) {
- m_Integral = (int64_t)dbvalue;
- m_Fractional = (FX_DWORD)(
- ((dbvalue > 0) ? (dbvalue - m_Integral) : (m_Integral - dbvalue)) *
- 4294967296);
- m_Exponent = 0;
-}
-CFX_LCNumeric::CFX_LCNumeric(CFX_WideString& wsNumeric) {
- FX_WStringToNumeric(wsNumeric, *this);
-}
-FX_FLOAT CFX_LCNumeric::GetFloat() const {
- FX_FLOAT dbRetValue = m_Fractional / 4294967296.0f;
- dbRetValue = m_Integral + (m_Integral >= 0 ? dbRetValue : -dbRetValue);
- if (m_Exponent != 0) {
- dbRetValue *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
- }
- return dbRetValue;
-}
-double CFX_LCNumeric::GetDouble() const {
- double value = m_Fractional / 4294967296.0;
- value = m_Integral + (m_Integral >= 0 ? value : -value);
- if (m_Exponent != 0) {
- value *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
- }
- return value;
-}
-CFX_WideString CFX_LCNumeric::ToString() const {
- return ToString(8, TRUE);
-}
-CFX_WideString CFX_LCNumeric::ToString(int32_t nTreading,
- FX_BOOL bTrimTailZeros) const {
-#ifdef FX_NUM_DOUBLE
- CFX_WideString wsResult;
- if (!m_wsValue.IsEmpty()) {
- const int32_t nIntegralMaxLen = 17;
- int32_t cc = 0;
- FX_BOOL bNegative = FALSE, bExpSign = FALSE;
- const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
- int32_t len = m_wsValue.GetLength();
- while (cc < len && FX_IsSpace(str[cc])) {
- cc++;
- }
- if (cc >= len) {
- return wsResult;
- }
- if (str[cc] == '+') {
- cc++;
- } else if (str[cc] == '-') {
- bNegative = TRUE;
- cc++;
- }
- int32_t nIntegralLen = 0;
- while (cc < len) {
- if (str[cc] == '.') {
- break;
- }
- if (!FX_IsDigit(str[cc])) {
- if ((str[cc] == 'E' || str[cc] == 'e')) {
- break;
- } else {
- return wsResult;
- }
- }
- if (nIntegralLen < nIntegralMaxLen) {
- *pIntegral = *pIntegral * 10 + str[cc] - '0';
- nIntegralLen++;
- }
- cc++;
- }
- *pIntegral = bNegative ? -*pIntegral : *pIntegral;
- if (cc < len && str[cc] == '.') {
- int scale = 0;
- double fraction = 0.0;
- cc++;
- while (cc < len) {
- if (scale >= gs_fraction_count) {
- while (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- break;
- }
- cc++;
- }
- }
- if (!FX_IsDigit(str[cc])) {
- if ((str[cc] == 'E' || str[cc] == 'e')) {
- break;
- } else {
- return FALSE;
- }
- }
- fraction += gs_fraction_scales[scale] * (str[cc] - '0');
- scale++;
- cc++;
- }
- *pFractional = (FX_DWORD)(fraction * 4294967296.0);
- }
- }
- double dbValeu = GetDouble();
- int64_t iInte = (int64_t)dbValeu;
- wsResult.Format(L"%l", (int64_t)iInte);
- if (m_Fractional) {
- CFX_WideString wsFormat;
- wsFormat.Format(L"%%.%dG", nTreading);
- double dblMantissa = (dbValeu > 0) ? (dbValeu - iInte) : (iInte - dbValeu);
- CFX_WideString wsFrac;
- wsFrac.Format((const FX_WCHAR*)wsFormat, dblMantissa);
- wsResult +=
- CFX_WideStringC((const FX_WCHAR*)wsFrac + 1, wsFrac.GetLength() - 1);
- if (bTrimTailZeros && nTreading > 0) {
- wsResult.TrimRight(L"0");
- wsResult.TrimRight(L".");
- }
- }
-#endif
- CFX_WideString wsFormat;
- wsFormat.Format(L"%%.%df", nTreading);
- CFX_WideString wsResult;
- wsResult.Format(wsFormat.c_str(), GetDouble());
- if (bTrimTailZeros && nTreading > 0) {
- wsResult.TrimRight(L"0");
- wsResult.TrimRight(L".");
- }
- return wsResult;
-}
-IFX_FormatString* IFX_FormatString::Create(IFX_LocaleMgr* pLocaleMgr,
- FX_BOOL bUseLCID) {
- if (!pLocaleMgr) {
- return NULL;
- }
- return new CFX_FormatString(pLocaleMgr, bUseLCID);
-}
-CFX_FormatString::CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID)
- : m_pLocaleMgr(pLocaleMgr), m_bUseLCID(bUseLCID) {}
-CFX_FormatString::~CFX_FormatString() {}
-void CFX_FormatString::SplitFormatString(const CFX_WideString& wsFormatString,
- CFX_WideStringArray& wsPatterns) {
- int32_t iStrLen = wsFormatString.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsFormatString;
- const FX_WCHAR* pToken = pStr;
- const FX_WCHAR* pEnd = pStr + iStrLen;
- FX_BOOL iQuote = FALSE;
- while (TRUE) {
- if (pStr >= pEnd) {
- CFX_WideString sub(pToken, pStr - pToken);
- wsPatterns.Add(sub);
- return;
- } else if (*pStr == '\'') {
- iQuote = !iQuote;
- } else if (*pStr == L'|' && !iQuote) {
- CFX_WideString sub(pToken, pStr - pToken);
- wsPatterns.Add(sub);
- pToken = pStr + 1;
- }
- pStr++;
- }
-}
-static CFX_WideString FX_GetLiteralText(const FX_WCHAR* pStrPattern,
- int32_t& iPattern,
- int32_t iLenPattern) {
- CFX_WideString wsOutput;
- if (pStrPattern[iPattern] != '\'') {
- return wsOutput;
- }
- iPattern++;
- int32_t iQuote = 1;
- while (iPattern < iLenPattern) {
- if (pStrPattern[iPattern] == '\'') {
- iQuote++;
- if ((iPattern + 1 >= iLenPattern) ||
- ((pStrPattern[iPattern + 1] != '\'') && (iQuote % 2 == 0))) {
- break;
- } else {
- iQuote++;
- }
- iPattern++;
- } else if (pStrPattern[iPattern] == '\\' && (iPattern + 1 < iLenPattern) &&
- pStrPattern[iPattern + 1] == 'u') {
- int32_t iKeyValue = 0;
- iPattern += 2;
- int32_t i = 0;
- while (iPattern < iLenPattern && i++ < 4) {
- FX_WCHAR ch = pStrPattern[iPattern++];
- if ((ch >= '0' && ch <= '9')) {
- iKeyValue = iKeyValue * 16 + ch - '0';
- } else if ((ch >= 'a' && ch <= 'f')) {
- iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
- } else if ((ch >= 'A' && ch <= 'F')) {
- iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
- }
- }
- if (iKeyValue != 0) {
- wsOutput += (FX_WCHAR)(iKeyValue & 0x0000FFFF);
- }
- continue;
- }
- wsOutput += pStrPattern[iPattern++];
- }
- return wsOutput;
-}
-static CFX_WideString FX_GetLiteralTextReverse(const FX_WCHAR* pStrPattern,
- int32_t& iPattern) {
- CFX_WideString wsOutput;
- if (pStrPattern[iPattern] != '\'') {
- return wsOutput;
- }
- iPattern--;
- int32_t iQuote = 1;
- while (iPattern >= 0) {
- if (pStrPattern[iPattern] == '\'') {
- iQuote++;
- if (iPattern - 1 >= 0 ||
- ((pStrPattern[iPattern - 1] != '\'') && (iQuote % 2 == 0))) {
- break;
- } else {
- iQuote++;
- }
- iPattern--;
- } else if (pStrPattern[iPattern] == '\\' &&
- pStrPattern[iPattern + 1] == 'u') {
- iPattern--;
- int32_t iKeyValue = 0;
- int32_t iLen = wsOutput.GetLength();
- int32_t i = 1;
- for (; i < iLen && i < 5; i++) {
- FX_WCHAR ch = wsOutput[i];
- if ((ch >= '0' && ch <= '9')) {
- iKeyValue = iKeyValue * 16 + ch - '0';
- } else if ((ch >= 'a' && ch <= 'f')) {
- iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
- } else if ((ch >= 'A' && ch <= 'F')) {
- iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
- }
- }
- if (iKeyValue != 0) {
- wsOutput.Delete(0, i);
- wsOutput = (FX_WCHAR)(iKeyValue & 0x0000FFFF) + wsOutput;
- }
- continue;
- }
- wsOutput = pStrPattern[iPattern--] + wsOutput;
- }
- return wsOutput;
-}
-FX_LOCALECATEGORY CFX_FormatString::GetCategory(
- const CFX_WideString& wsPattern) {
- FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
- int32_t ccf = 0;
- int32_t iLenf = wsPattern.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
- FX_BOOL bBraceOpen = FALSE;
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- FX_GetLiteralText(pStr, ccf, iLenf);
- } else if (!bBraceOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
- CFX_WideString wsCategory(pStr[ccf]);
- ccf++;
- while (TRUE) {
- if (ccf == iLenf) {
- return eCategory;
- }
- if (pStr[ccf] == '.' || pStr[ccf] == '(') {
- break;
- }
- if (pStr[ccf] == '{') {
- bBraceOpen = TRUE;
- break;
- }
- wsCategory += pStr[ccf];
- ccf++;
- }
- FX_DWORD dwHash =
- FX_HashCode_String_GetW(wsCategory, wsCategory.GetLength());
- if (dwHash == FX_LOCALECATEGORY_DateHash) {
- if (eCategory == FX_LOCALECATEGORY_Time) {
- return FX_LOCALECATEGORY_DateTime;
- }
- eCategory = FX_LOCALECATEGORY_Date;
- } else if (dwHash == FX_LOCALECATEGORY_TimeHash) {
- if (eCategory == FX_LOCALECATEGORY_Date) {
- return FX_LOCALECATEGORY_DateTime;
- }
- eCategory = FX_LOCALECATEGORY_Time;
- } else if (dwHash == FX_LOCALECATEGORY_DateTimeHash) {
- return FX_LOCALECATEGORY_DateTime;
- } else if (dwHash == FX_LOCALECATEGORY_TextHash) {
- return FX_LOCALECATEGORY_Text;
- } else if (dwHash == FX_LOCALECATEGORY_NumHash) {
- return FX_LOCALECATEGORY_Num;
- } else if (dwHash == FX_LOCALECATEGORY_ZeroHash) {
- return FX_LOCALECATEGORY_Zero;
- } else if (dwHash == FX_LOCALECATEGORY_NullHash) {
- return FX_LOCALECATEGORY_Null;
- }
- } else if (pStr[ccf] == '}') {
- bBraceOpen = FALSE;
- }
- ccf++;
- }
- return eCategory;
-}
-static FX_WORD FX_WStringToLCID(const FX_WCHAR* pstrLCID) {
- if (!pstrLCID) {
- return 0;
- }
- wchar_t* pEnd;
- return (FX_WORD)wcstol((wchar_t*)pstrLCID, &pEnd, 16);
-}
-FX_WORD CFX_FormatString::GetLCID(const CFX_WideString& wsPattern) {
- return FX_WStringToLCID(GetLocaleName(wsPattern));
-}
-CFX_WideString CFX_FormatString::GetLocaleName(
- const CFX_WideString& wsPattern) {
- int32_t ccf = 0;
- int32_t iLenf = wsPattern.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- FX_GetLiteralText(pStr, ccf, iLenf);
- } else if (pStr[ccf] == '(') {
- ccf++;
- CFX_WideString wsLCID;
- while (ccf < iLenf && pStr[ccf] != ')') {
- wsLCID += pStr[ccf++];
- }
- return wsLCID;
- }
- ccf++;
- }
- return CFX_WideString();
-}
-IFX_Locale* CFX_FormatString::GetTextFormat(const CFX_WideString& wsPattern,
- const CFX_WideStringC& wsCategory,
- CFX_WideString& wsPurgePattern) {
- IFX_Locale* pLocale = NULL;
- int32_t ccf = 0;
- int32_t iLenf = wsPattern.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
- FX_BOOL bBrackOpen = FALSE;
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- int32_t iCurChar = ccf;
- FX_GetLiteralText(pStr, ccf, iLenf);
- wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
- } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
- CFX_WideString wsSearchCategory(pStr[ccf]);
- ccf++;
- while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
- pStr[ccf] != '(') {
- wsSearchCategory += pStr[ccf];
- ccf++;
- }
- if (wsSearchCategory != wsCategory) {
- continue;
- }
- while (ccf < iLenf) {
- if (pStr[ccf] == '(') {
- ccf++;
- CFX_WideString wsLCID;
- while (ccf < iLenf && pStr[ccf] != ')') {
- wsLCID += pStr[ccf++];
- }
- pLocale = GetPatternLocale(wsLCID);
- } else if (pStr[ccf] == '{') {
- bBrackOpen = TRUE;
- break;
- }
- ccf++;
- }
- } else if (pStr[ccf] != '}') {
- wsPurgePattern += pStr[ccf];
- }
- ccf++;
- }
- if (!bBrackOpen) {
- wsPurgePattern = wsPattern;
- }
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- return pLocale;
-}
-#define FX_NUMSTYLE_Percent 0x01
-#define FX_NUMSTYLE_Exponent 0x02
-#define FX_NUMSTYLE_DotVorv 0x04
-IFX_Locale* CFX_FormatString::GetNumericFormat(const CFX_WideString& wsPattern,
- int32_t& iDotIndex,
- FX_DWORD& dwStyle,
- CFX_WideString& wsPurgePattern) {
- dwStyle = 0;
- IFX_Locale* pLocale = NULL;
- int32_t ccf = 0;
- int32_t iLenf = wsPattern.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
- FX_BOOL bFindDot = FALSE;
- FX_BOOL bBrackOpen = FALSE;
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- int32_t iCurChar = ccf;
- FX_GetLiteralText(pStr, ccf, iLenf);
- wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
- } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
- CFX_WideString wsCategory(pStr[ccf]);
- ccf++;
- while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
- pStr[ccf] != '(') {
- wsCategory += pStr[ccf];
- ccf++;
- }
- if (wsCategory != FX_WSTRC(L"num")) {
- bBrackOpen = TRUE;
- ccf = 0;
- continue;
- }
- while (ccf < iLenf) {
- if (pStr[ccf] == '(') {
- ccf++;
- CFX_WideString wsLCID;
- while (ccf < iLenf && pStr[ccf] != ')') {
- wsLCID += pStr[ccf++];
- }
- pLocale = GetPatternLocale(wsLCID);
- } else if (pStr[ccf] == '{') {
- bBrackOpen = TRUE;
- break;
- } else if (pStr[ccf] == '.') {
- CFX_WideString wsSubCategory;
- ccf++;
- while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
- wsSubCategory += pStr[ccf++];
- }
- FX_DWORD dwSubHash =
- FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
- FX_LOCALENUMSUBCATEGORY eSubCategory = FX_LOCALENUMPATTERN_Decimal;
- for (int32_t i = 0; i < g_iFXLocaleNumSubCatCount; i++) {
- if (g_FXLocaleNumSubCatData[i].uHash == dwSubHash) {
- eSubCategory = (FX_LOCALENUMSUBCATEGORY)g_FXLocaleNumSubCatData[i]
- .eSubCategory;
- break;
- }
- }
- wsSubCategory.Empty();
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- FXSYS_assert(pLocale != NULL);
- pLocale->GetNumPattern(eSubCategory, wsSubCategory);
- iDotIndex = wsSubCategory.Find('.');
- if (iDotIndex > 0) {
- iDotIndex += wsPurgePattern.GetLength();
- bFindDot = TRUE;
- dwStyle |= FX_NUMSTYLE_DotVorv;
- }
- wsPurgePattern += wsSubCategory;
- if (eSubCategory == FX_LOCALENUMPATTERN_Percent) {
- dwStyle |= FX_NUMSTYLE_Percent;
- }
- continue;
- }
- ccf++;
- }
- } else if (pStr[ccf] == 'E') {
- dwStyle |= FX_NUMSTYLE_Exponent;
- wsPurgePattern += pStr[ccf];
- } else if (pStr[ccf] == '%') {
- dwStyle |= FX_NUMSTYLE_Percent;
- wsPurgePattern += pStr[ccf];
- } else if (pStr[ccf] != '}') {
- wsPurgePattern += pStr[ccf];
- }
- if (!bFindDot) {
- if (pStr[ccf] == '.' || pStr[ccf] == 'V' || pStr[ccf] == 'v') {
- bFindDot = TRUE;
- iDotIndex = wsPurgePattern.GetLength() - 1;
- dwStyle |= FX_NUMSTYLE_DotVorv;
- }
- }
- ccf++;
- }
- if (!bFindDot) {
- iDotIndex = wsPurgePattern.GetLength();
- }
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- return pLocale;
-}
-static FX_BOOL FX_GetNumericDotIndex(const CFX_WideString& wsNum,
- const CFX_WideString& wsDotSymbol,
- int32_t& iDotIndex) {
- int32_t ccf = 0;
- int32_t iLenf = wsNum.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsNum;
- int32_t iLenDot = wsDotSymbol.GetLength();
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- FX_GetLiteralText(pStr, ccf, iLenf);
- } else if (ccf + iLenDot <= iLenf &&
- !FXSYS_wcsncmp(pStr + ccf, (const FX_WCHAR*)wsDotSymbol,
- iLenDot)) {
- iDotIndex = ccf;
- return TRUE;
- }
- ccf++;
- }
- iDotIndex = wsNum.Find('.');
- if (iDotIndex < 0) {
- iDotIndex = iLenf;
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CFX_FormatString::ParseText(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsValue) {
- wsValue.Empty();
- if (wsSrcText.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
- if (wsTextFormat.IsEmpty()) {
- return FALSE;
- }
- int32_t iText = 0, iPattern = 0;
- const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
- int32_t iLenText = wsSrcText.GetLength();
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern && iText < iLenText) {
- switch (pStrPattern[iPattern]) {
- case '\'': {
- CFX_WideString wsLiteral =
- FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (iText + iLiteralLen > iLenText ||
- FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- wsValue = wsSrcText;
- return FALSE;
- }
- iText += iLiteralLen;
- iPattern++;
- break;
- }
- case 'A':
- if (FX_IsAlpha(pStrText[iText])) {
- wsValue += pStrText[iText];
- iText++;
- }
- iPattern++;
- break;
- case 'X':
- wsValue += pStrText[iText];
- iText++;
- iPattern++;
- break;
- case 'O':
- case '0':
- if (FX_IsDigit(pStrText[iText]) || FX_IsAlpha(pStrText[iText])) {
- wsValue += pStrText[iText];
- iText++;
- }
- iPattern++;
- break;
- case '9':
- if (FX_IsDigit(pStrText[iText])) {
- wsValue += pStrText[iText];
- iText++;
- }
- iPattern++;
- break;
- default:
- if (pStrPattern[iPattern] != pStrText[iText]) {
- wsValue = wsSrcText;
- return FALSE;
- }
- iPattern++;
- iText++;
- break;
- }
- }
- return iPattern == iLenPattern && iText == iLenText;
-}
-FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- FX_FLOAT& fValue) {
- fValue = 0.0f;
- if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- int32_t dot_index_f = -1;
- FX_DWORD dwFormatStyle = 0;
- CFX_WideString wsNumFormat;
- IFX_Locale* pLocale =
- GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
- if (!pLocale || wsNumFormat.IsEmpty()) {
- return FALSE;
- }
- int32_t iExponent = 0;
- CFX_WideString wsDotSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
- CFX_WideString wsGroupSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
- int32_t iGroupLen = wsGroupSymbol.GetLength();
- CFX_WideString wsMinus;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
- int32_t iMinusLen = wsMinus.GetLength();
- int cc = 0, ccf = 0;
- const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
- int len = wsSrcNum.GetLength();
- const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
- int lenf = wsNumFormat.GetLength();
- double dbRetValue = 0;
- double coeff = 1;
- FX_BOOL bHavePercentSymbol = FALSE;
- FX_BOOL bNeg = FALSE;
- FX_BOOL bReverseParse = FALSE;
- int32_t dot_index = 0;
- if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) &&
- (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
- bReverseParse = TRUE;
- }
- bReverseParse = FALSE;
- if (bReverseParse) {
- ccf = lenf - 1;
- cc = len - 1;
- while (ccf > dot_index_f && cc >= 0) {
- switch (strf[ccf]) {
- case '\'': {
- CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- cc -= iLiteralLen - 1;
- if (cc < 0 || FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- }
- case '9':
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
- coeff *= 0.1;
- cc--;
- ccf--;
- break;
- case 'z':
- if (cc >= 0) {
- dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
- coeff *= 0.1;
- cc--;
- }
- ccf--;
- break;
- case 'Z':
- if (str[cc] != ' ') {
- dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
- coeff *= 0.1;
- }
- cc--;
- ccf--;
- break;
- case 'S':
- if (str[cc] == '+' || str[cc] == ' ') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 's':
- if (str[cc] == '+') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 'E': {
- if (cc >= dot_index) {
- return FALSE;
- }
- FX_BOOL bExpSign = FALSE;
- while (cc >= 0) {
- if (str[cc] == 'E' || str[cc] == 'e') {
- break;
- }
- if (FX_IsDigit(str[cc])) {
- iExponent = iExponent + (str[cc] - '0') * 10;
- cc--;
- continue;
- } else if (str[cc] == '+') {
- cc--;
- continue;
- } else if (cc - iMinusLen + 1 > 0 &&
- !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
- (const FX_WCHAR*)wsMinus, iMinusLen)) {
- bExpSign = TRUE;
- cc -= iMinusLen;
- } else {
- return FALSE;
- }
- }
- cc--;
- iExponent = bExpSign ? -iExponent : iExponent;
- ccf--;
- } break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
- wsSymbol);
- int32_t iSymbolLen = wsSymbol.GetLength();
- cc -= iSymbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- } break;
- case 'r':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
- if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'R':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'b':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
- if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'B':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case '.':
- case 'V':
- case 'v':
- return FALSE;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- int32_t iSysmbolLen = wsSymbol.GetLength();
- cc -= iSysmbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- bHavePercentSymbol = TRUE;
- } break;
- case '8':
- while (ccf < lenf && strf[ccf] == '8') {
- ccf++;
- }
- while (cc < len && FX_IsDigit(str[cc])) {
- dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
- coeff *= 0.1;
- cc++;
- }
- break;
- case ',': {
- if (cc >= 0) {
- cc -= iGroupLen - 1;
- if (cc >= 0 &&
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
- iGroupLen) == 0) {
- cc--;
- } else {
- cc += iGroupLen - 1;
- }
- }
- ccf--;
- } break;
- case '(':
- if (str[cc] == L'(') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- case ')':
- if (str[cc] == L')') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- default:
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc--;
- ccf--;
- }
- }
- dot_index = cc + 1;
- }
- ccf = dot_index_f - 1;
- cc = dot_index - 1;
- coeff = 1;
- while (ccf >= 0 && cc >= 0) {
- switch (strf[ccf]) {
- case '\'': {
- CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- cc -= iLiteralLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- }
- case '9':
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 10;
- cc--;
- ccf--;
- break;
- case 'z':
- if (FX_IsDigit(str[cc])) {
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 10;
- cc--;
- }
- ccf--;
- break;
- case 'Z':
- if (str[cc] != ' ') {
- if (FX_IsDigit(str[cc])) {
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 10;
- cc--;
- }
- } else {
- cc--;
- }
- ccf--;
- break;
- case 'S':
- if (str[cc] == '+' || str[cc] == ' ') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 's':
- if (str[cc] == '+') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 'E': {
- if (cc >= dot_index) {
- return FALSE;
- }
- FX_BOOL bExpSign = FALSE;
- while (cc >= 0) {
- if (str[cc] == 'E' || str[cc] == 'e') {
- break;
- }
- if (FX_IsDigit(str[cc])) {
- iExponent = iExponent + (str[cc] - '0') * 10;
- cc--;
- continue;
- } else if (str[cc] == '+') {
- cc--;
- continue;
- } else if (cc - iMinusLen + 1 > 0 &&
- !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
- (const FX_WCHAR*)wsMinus, iMinusLen)) {
- bExpSign = TRUE;
- cc -= iMinusLen;
- } else {
- return FALSE;
- }
- }
- cc--;
- iExponent = bExpSign ? -iExponent : iExponent;
- ccf--;
- } break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- int32_t iSymbolLen = wsSymbol.GetLength();
- cc -= iSymbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- } break;
- case 'r':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
- if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'R':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'b':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
- if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'B':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case '.':
- case 'V':
- case 'v':
- return FALSE;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- int32_t iSysmbolLen = wsSymbol.GetLength();
- cc -= iSysmbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- bHavePercentSymbol = TRUE;
- } break;
- case '8':
- return FALSE;
- case ',': {
- if (cc >= 0) {
- cc -= iGroupLen - 1;
- if (cc >= 0 &&
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
- iGroupLen) == 0) {
- cc--;
- } else {
- cc += iGroupLen - 1;
- }
- }
- ccf--;
- } break;
- case '(':
- if (str[cc] == L'(') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- case ')':
- if (str[cc] == L')') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- default:
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc--;
- ccf--;
- }
- }
- if (cc >= 0) {
- return FALSE;
- }
- if (!bReverseParse) {
- ccf = dot_index_f + 1;
- cc = (dot_index == len) ? len : dot_index + 1;
- coeff = 0.1;
- while (cc < len && ccf < lenf) {
- switch (strf[ccf]) {
- case '\'': {
- CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (cc + iLiteralLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- return FALSE;
- }
- cc += iLiteralLen;
- ccf++;
- break;
- }
- case '9':
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- {
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 0.1;
- }
- cc++;
- ccf++;
- break;
- case 'z':
- if (FX_IsDigit(str[cc])) {
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 0.1;
- cc++;
- }
- ccf++;
- break;
- case 'Z':
- if (str[cc] != ' ') {
- if (FX_IsDigit(str[cc])) {
- dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
- coeff *= 0.1;
- cc++;
- }
- } else {
- cc++;
- }
- ccf++;
- break;
- case 'S':
- if (str[cc] == '+' || str[cc] == ' ') {
- cc++;
- } else {
- if (cc + iMinusLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- bNeg = TRUE;
- cc += iMinusLen;
- }
- ccf++;
- break;
- case 's':
- if (str[cc] == '+') {
- cc++;
- } else {
- if (cc + iMinusLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- bNeg = TRUE;
- cc += iMinusLen;
- }
- ccf++;
- break;
- case 'E': {
- if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
- return FALSE;
- }
- FX_BOOL bExpSign = FALSE;
- cc++;
- if (cc < len) {
- if (str[cc] == '+') {
- cc++;
- } else if (str[cc] == '-') {
- bExpSign = TRUE;
- cc++;
- }
- }
- while (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- break;
- }
- iExponent = iExponent * 10 + str[cc] - '0';
- cc++;
- }
- iExponent = bExpSign ? -iExponent : iExponent;
- ccf++;
- } break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
- wsSymbol);
- int32_t iSymbolLen = wsSymbol.GetLength();
- if (cc + iSymbolLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
- return FALSE;
- }
- cc += iSymbolLen;
- ccf++;
- } break;
- case 'c':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
- if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'C':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'd':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
- if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'D':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case '.':
- case 'V':
- case 'v':
- return FALSE;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- int32_t iSysmbolLen = wsSymbol.GetLength();
- if (cc + iSysmbolLen <= len &&
- !FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol,
- iSysmbolLen)) {
- cc += iSysmbolLen;
- }
- ccf++;
- bHavePercentSymbol = TRUE;
- } break;
- case '8': {
- while (ccf < lenf && strf[ccf] == '8') {
- ccf++;
- }
- while (cc < len && FX_IsDigit(str[cc])) {
- dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
- coeff *= 0.1;
- cc++;
- }
- } break;
- case ',': {
- if (cc + iGroupLen <= len &&
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
- iGroupLen) == 0) {
- cc += iGroupLen;
- }
- ccf++;
- } break;
- case '(':
- if (str[cc] == L'(') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc++;
- ccf++;
- break;
- case ')':
- if (str[cc] == L')') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc++;
- ccf++;
- break;
- default:
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc++;
- ccf++;
- }
- }
- if (cc != len) {
- return FALSE;
- }
- }
- if (iExponent) {
- dbRetValue *= FXSYS_pow(10, (FX_FLOAT)iExponent);
- }
- if (bHavePercentSymbol) {
- dbRetValue /= 100.0;
- }
- if (bNeg) {
- dbRetValue = -dbRetValue;
- }
- fValue = (FX_FLOAT)dbRetValue;
- return TRUE;
-}
-void FX_ParseNumString(const CFX_WideString& wsNum, CFX_WideString& wsResult) {
- int32_t iCount = wsNum.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsNum;
- FX_WCHAR* pDst = wsResult.GetBuffer(iCount);
- int32_t nIndex = 0;
- FX_BOOL bMinus = FALSE;
- int32_t i = 0;
- for (i = 0; i < iCount; i++) {
- FX_WCHAR wc = pStr[i];
- if (wc == '.') {
- break;
- }
- if ((wc == L'0' || wc == L' ' || wc == '+') && nIndex == 0) {
- continue;
- }
- if (wc == '-') {
- pDst[nIndex++] = wc;
- bMinus = TRUE;
- continue;
- }
- if (wc == L'0' && nIndex == 1 && bMinus) {
- continue;
- }
- pDst[nIndex++] = wc;
- }
- if (bMinus && nIndex == 1) {
- pDst[nIndex++] = '0';
- }
- if (nIndex == 0) {
- wsResult.ReleaseBuffer(0);
- pDst = wsResult.GetBuffer(iCount + 1);
- pDst[nIndex++] = '0';
- }
- int32_t j = 0;
- for (j = iCount - 1; j > i; j--) {
- FX_WCHAR wc = pStr[j];
- if (wc != L'0' && wc != L' ') {
- break;
- }
- }
- if (j > i) {
- pDst[nIndex++] = '.';
- FXSYS_wcsncpy(pDst + nIndex, pStr + i + 1, j - i);
- nIndex += j - i;
- }
- wsResult.ReleaseBuffer(nIndex);
-}
-FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsValue) {
- wsValue.Empty();
- if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- int32_t dot_index_f = -1;
- FX_DWORD dwFormatStyle = 0;
- CFX_WideString wsNumFormat;
- IFX_Locale* pLocale =
- GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
- if (!pLocale || wsNumFormat.IsEmpty()) {
- return FALSE;
- }
- int32_t iExponent = 0;
- CFX_WideString wsDotSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
- CFX_WideString wsGroupSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
- int32_t iGroupLen = wsGroupSymbol.GetLength();
- CFX_WideString wsMinus;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
- int32_t iMinusLen = wsMinus.GetLength();
- int cc = 0, ccf = 0;
- const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
- int len = wsSrcNum.GetLength();
- const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
- int lenf = wsNumFormat.GetLength();
- FX_BOOL bHavePercentSymbol = FALSE;
- FX_BOOL bNeg = FALSE;
- FX_BOOL bReverseParse = FALSE;
- int32_t dot_index = 0;
- if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) &&
- (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
- bReverseParse = TRUE;
- }
- bReverseParse = FALSE;
- ccf = dot_index_f - 1;
- cc = dot_index - 1;
- while (ccf >= 0 && cc >= 0) {
- switch (strf[ccf]) {
- case '\'': {
- CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- cc -= iLiteralLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- }
- case '9':
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wsValue = CFX_WideStringC(str[cc]) + wsValue;
- cc--;
- ccf--;
- break;
- case 'z':
- if (FX_IsDigit(str[cc])) {
- wsValue = CFX_WideStringC(str[cc]) + wsValue;
- cc--;
- }
- ccf--;
- break;
- case 'Z':
- if (str[cc] != ' ') {
- if (FX_IsDigit(str[cc])) {
- wsValue = CFX_WideStringC(str[cc]) + wsValue;
- cc--;
- }
- } else {
- cc--;
- }
- ccf--;
- break;
- case 'S':
- if (str[cc] == '+' || str[cc] == ' ') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 's':
- if (str[cc] == '+') {
- cc--;
- } else {
- cc -= iMinusLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- cc--;
- bNeg = TRUE;
- }
- ccf--;
- break;
- case 'E': {
- if (cc >= dot_index) {
- return FALSE;
- }
- FX_BOOL bExpSign = FALSE;
- while (cc >= 0) {
- if (str[cc] == 'E' || str[cc] == 'e') {
- break;
- }
- if (FX_IsDigit(str[cc])) {
- iExponent = iExponent + (str[cc] - '0') * 10;
- cc--;
- continue;
- } else if (str[cc] == '+') {
- cc--;
- continue;
- } else if (cc - iMinusLen + 1 > 0 &&
- !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
- (const FX_WCHAR*)wsMinus, iMinusLen)) {
- bExpSign = TRUE;
- cc -= iMinusLen;
- } else {
- return FALSE;
- }
- }
- cc--;
- iExponent = bExpSign ? -iExponent : iExponent;
- ccf--;
- } break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- int32_t iSymbolLen = wsSymbol.GetLength();
- cc -= iSymbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- } break;
- case 'r':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
- if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'R':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'b':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
- if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case 'B':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
- bNeg = TRUE;
- cc -= 2;
- }
- ccf -= 2;
- } else {
- ccf--;
- }
- break;
- case '.':
- case 'V':
- case 'v':
- return FALSE;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- int32_t iSysmbolLen = wsSymbol.GetLength();
- cc -= iSysmbolLen - 1;
- if (cc < 0 ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
- return FALSE;
- }
- cc--;
- ccf--;
- bHavePercentSymbol = TRUE;
- } break;
- case '8':
- return FALSE;
- case ',': {
- if (cc >= 0) {
- cc -= iGroupLen - 1;
- if (cc >= 0 &&
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
- iGroupLen) == 0) {
- cc--;
- } else {
- cc += iGroupLen - 1;
- }
- }
- ccf--;
- } break;
- case '(':
- if (str[cc] == L'(') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- case ')':
- if (str[cc] == L')') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc--;
- ccf--;
- break;
- default:
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc--;
- ccf--;
- }
- }
- if (cc >= 0) {
- if (str[cc] == '-') {
- bNeg = TRUE;
- cc--;
- }
- if (cc >= 0) {
- return FALSE;
- }
- }
- if (dot_index < len && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
- wsValue += '.';
- }
- if (!bReverseParse) {
- ccf = dot_index_f + 1;
- cc = (dot_index == len) ? len : dot_index + 1;
- while (cc < len && ccf < lenf) {
- switch (strf[ccf]) {
- case '\'': {
- CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (cc + iLiteralLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- return FALSE;
- }
- cc += iLiteralLen;
- ccf++;
- break;
- }
- case '9':
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- { wsValue += str[cc]; }
- cc++;
- ccf++;
- break;
- case 'z':
- if (FX_IsDigit(str[cc])) {
- wsValue += str[cc];
- cc++;
- }
- ccf++;
- break;
- case 'Z':
- if (str[cc] != ' ') {
- if (FX_IsDigit(str[cc])) {
- wsValue += str[cc];
- cc++;
- }
- } else {
- cc++;
- }
- ccf++;
- break;
- case 'S':
- if (str[cc] == '+' || str[cc] == ' ') {
- cc++;
- } else {
- if (cc + iMinusLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- bNeg = TRUE;
- cc += iMinusLen;
- }
- ccf++;
- break;
- case 's':
- if (str[cc] == '+') {
- cc++;
- } else {
- if (cc + iMinusLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
- return FALSE;
- }
- bNeg = TRUE;
- cc += iMinusLen;
- }
- ccf++;
- break;
- case 'E': {
- if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
- return FALSE;
- }
- FX_BOOL bExpSign = FALSE;
- cc++;
- if (cc < len) {
- if (str[cc] == '+') {
- cc++;
- } else if (str[cc] == '-') {
- bExpSign = TRUE;
- cc++;
- }
- }
- while (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- break;
- }
- iExponent = iExponent * 10 + str[cc] - '0';
- cc++;
- }
- iExponent = bExpSign ? -iExponent : iExponent;
- ccf++;
- } break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
- wsSymbol);
- int32_t iSymbolLen = wsSymbol.GetLength();
- if (cc + iSymbolLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
- return FALSE;
- }
- cc += iSymbolLen;
- ccf++;
- } break;
- case 'c':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
- if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'C':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'd':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
- if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case 'D':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
- if (str[cc] == ' ') {
- cc++;
- } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
- bNeg = TRUE;
- cc += 2;
- }
- ccf += 2;
- }
- break;
- case '.':
- case 'V':
- case 'v':
- return FALSE;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- int32_t iSysmbolLen = wsSymbol.GetLength();
- if (cc + iSysmbolLen <= len &&
- !FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol,
- iSysmbolLen)) {
- cc += iSysmbolLen;
- }
- ccf++;
- bHavePercentSymbol = TRUE;
- } break;
- case '8': {
- while (ccf < lenf && strf[ccf] == '8') {
- ccf++;
- }
- while (cc < len && FX_IsDigit(str[cc])) {
- wsValue += str[cc];
- cc++;
- }
- } break;
- case ',': {
- if (cc + iGroupLen <= len &&
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
- iGroupLen) == 0) {
- cc += iGroupLen;
- }
- ccf++;
- } break;
- case '(':
- if (str[cc] == L'(') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc++;
- ccf++;
- break;
- case ')':
- if (str[cc] == L')') {
- bNeg = TRUE;
- } else if (str[cc] != L' ') {
- return FALSE;
- }
- cc++;
- ccf++;
- break;
- default:
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc++;
- ccf++;
- }
- }
- if (cc != len) {
- return FALSE;
- }
- }
- if (iExponent || bHavePercentSymbol) {
- CFX_Decimal decimal = CFX_Decimal(wsValue);
- if (iExponent) {
- decimal = decimal * CFX_Decimal(FXSYS_pow(10, (FX_FLOAT)iExponent));
- }
- if (bHavePercentSymbol) {
- decimal = decimal / CFX_Decimal(100);
- }
- wsValue = decimal;
- }
- if (bNeg) {
- wsValue = CFX_WideStringC('-') + wsValue;
- }
- return TRUE;
-}
-FX_DATETIMETYPE CFX_FormatString::GetDateTimeFormat(
- const CFX_WideString& wsPattern,
- IFX_Locale*& pLocale,
- CFX_WideString& wsDatePattern,
- CFX_WideString& wsTimePattern) {
- pLocale = NULL;
- CFX_WideString wsTempPattern;
- FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
- int32_t ccf = 0;
- int32_t iLenf = wsPattern.GetLength();
- const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
- int32_t iFindCategory = 0;
- FX_BOOL bBraceOpen = FALSE;
- while (ccf < iLenf) {
- if (pStr[ccf] == '\'') {
- int32_t iCurChar = ccf;
- FX_GetLiteralText(pStr, ccf, iLenf);
- wsTempPattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
- } else if (!bBraceOpen && iFindCategory != 3 &&
- FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
- CFX_WideString wsCategory(pStr[ccf]);
- ccf++;
- while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
- pStr[ccf] != '(') {
- if (pStr[ccf] == 'T') {
- wsDatePattern = wsPattern.Left(ccf);
- wsTimePattern = wsPattern.Right(wsPattern.GetLength() - ccf);
- wsTimePattern.SetAt(0, ' ');
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- return FX_DATETIMETYPE_DateTime;
- }
- wsCategory += pStr[ccf];
- ccf++;
- }
- if (!(iFindCategory & 1) && wsCategory == FX_WSTRC(L"date")) {
- iFindCategory |= 1;
- eCategory = FX_LOCALECATEGORY_Date;
- if (iFindCategory & 2) {
- iFindCategory = 4;
- }
- } else if (!(iFindCategory & 2) && wsCategory == FX_WSTRC(L"time")) {
- iFindCategory |= 2;
- eCategory = FX_LOCALECATEGORY_Time;
- } else if (wsCategory == FX_WSTRC(L"datetime")) {
- iFindCategory = 3;
- eCategory = FX_LOCALECATEGORY_DateTime;
- } else {
- continue;
- }
- while (ccf < iLenf) {
- if (pStr[ccf] == '(') {
- ccf++;
- CFX_WideString wsLCID;
- while (ccf < iLenf && pStr[ccf] != ')') {
- wsLCID += pStr[ccf++];
- }
- pLocale = GetPatternLocale(wsLCID);
- } else if (pStr[ccf] == '{') {
- bBraceOpen = TRUE;
- break;
- } else if (pStr[ccf] == '.') {
- CFX_WideString wsSubCategory;
- ccf++;
- while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
- wsSubCategory += pStr[ccf++];
- }
- FX_DWORD dwSubHash =
- FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
- FX_LOCALEDATETIMESUBCATEGORY eSubCategory =
- FX_LOCALEDATETIMESUBCATEGORY_Medium;
- for (int32_t i = 0; i < g_iFXLocaleDateTimeSubCatCount; i++) {
- if (g_FXLocaleDateTimeSubCatData[i].uHash == dwSubHash) {
- eSubCategory =
- (FX_LOCALEDATETIMESUBCATEGORY)g_FXLocaleDateTimeSubCatData[i]
- .eSubCategory;
- break;
- }
- }
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- FXSYS_assert(pLocale != NULL);
- switch (eCategory) {
- case FX_LOCALECATEGORY_Date:
- pLocale->GetDatePattern(eSubCategory, wsDatePattern);
- wsDatePattern = wsTempPattern + wsDatePattern;
- break;
- case FX_LOCALECATEGORY_Time:
- pLocale->GetTimePattern(eSubCategory, wsTimePattern);
- wsTimePattern = wsTempPattern + wsTimePattern;
- break;
- case FX_LOCALECATEGORY_DateTime:
- pLocale->GetDatePattern(eSubCategory, wsDatePattern);
- wsDatePattern = wsTempPattern + wsDatePattern;
- pLocale->GetTimePattern(eSubCategory, wsTimePattern);
- break;
- default:
- break;
- }
- wsTempPattern.Empty();
- continue;
- }
- ccf++;
- }
- } else if (pStr[ccf] == '}') {
- bBraceOpen = FALSE;
- if (!wsTempPattern.IsEmpty()) {
- if (eCategory == FX_LOCALECATEGORY_Time) {
- wsTimePattern = wsTempPattern;
- } else if (eCategory == FX_LOCALECATEGORY_Date) {
- wsDatePattern = wsTempPattern;
- }
- wsTempPattern.Empty();
- }
- } else {
- wsTempPattern += pStr[ccf];
- }
- ccf++;
- }
- if (!wsTempPattern.IsEmpty()) {
- if (eCategory == FX_LOCALECATEGORY_Date) {
- wsDatePattern += wsTempPattern;
- } else {
- wsTimePattern += wsTempPattern;
- }
- }
- if (!pLocale) {
- pLocale = m_pLocaleMgr->GetDefLocale();
- }
- if (!iFindCategory) {
- wsTimePattern.Empty();
- wsDatePattern = wsPattern;
- }
- return (FX_DATETIMETYPE)iFindCategory;
-}
-static FX_BOOL FX_ParseLocaleDate(const CFX_WideString& wsDate,
- const CFX_WideString& wsDatePattern,
- IFX_Locale* pLocale,
- CFX_Unitime& datetime,
- int32_t& cc) {
- int32_t year = 1900;
- int32_t month = 1;
- int32_t day = 1;
- int32_t ccf = 0;
- const FX_WCHAR* str = (const FX_WCHAR*)wsDate;
- int32_t len = wsDate.GetLength();
- const FX_WCHAR* strf = (const FX_WCHAR*)wsDatePattern;
- int32_t lenf = wsDatePattern.GetLength();
- while (cc < len && ccf < lenf) {
- if (strf[ccf] == '\'') {
- CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (cc + iLiteralLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
- return FALSE;
- }
- cc += iLiteralLen;
- ccf++;
- continue;
- } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc++;
- ccf++;
- continue;
- }
- FX_DWORD dwSymbolNum = 1;
- FX_DWORD dwSymbol = strf[ccf++];
- while (ccf < lenf && strf[ccf] == dwSymbol) {
- ccf++;
- dwSymbolNum++;
- }
- dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
- if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- day = str[cc++] - '0';
- if (cc < len && FX_IsDigit(str[cc])) {
- day = day * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- day = str[cc++] - '0';
- if (cc < len) {
- day = day * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
- int i = 0;
- while (cc < len && i < 3 && FX_IsDigit(str[cc])) {
- cc++;
- i++;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
- cc += 3;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- month = str[cc++] - '0';
- if (cc < len && FX_IsDigit(str[cc])) {
- month = month * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- month = str[cc++] - '0';
- if (cc < len) {
- month = month * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
- CFX_WideString wsMonthNameAbbr;
- FX_WORD i = 0;
- for (; i < 12; i++) {
- pLocale->GetMonthName(i, wsMonthNameAbbr, TRUE);
- if (wsMonthNameAbbr.IsEmpty()) {
- continue;
- }
- if (!FXSYS_wcsncmp((const FX_WCHAR*)wsMonthNameAbbr, str + cc,
- wsMonthNameAbbr.GetLength())) {
- break;
- }
- }
- if (i < 12) {
- cc += wsMonthNameAbbr.GetLength();
- month = i + 1;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
- CFX_WideString wsMonthName;
- FX_WORD i = 0;
- for (; i < 12; i++) {
- pLocale->GetMonthName(i, wsMonthName, FALSE);
- if (wsMonthName.IsEmpty()) {
- continue;
- }
- if (!FXSYS_wcsncmp((const FX_WCHAR*)wsMonthName, str + cc,
- wsMonthName.GetLength())) {
- break;
- }
- }
- if (i < 12) {
- cc += wsMonthName.GetLength();
- month = i + 1;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
- cc += 1;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
- CFX_WideString wsDayNameAbbr;
- FX_WORD i = 0;
- for (; i < 7; i++) {
- pLocale->GetDayName(i, wsDayNameAbbr, TRUE);
- if (wsDayNameAbbr.IsEmpty()) {
- continue;
- }
- if (!FXSYS_wcsncmp((const FX_WCHAR*)wsDayNameAbbr, str + cc,
- wsDayNameAbbr.GetLength())) {
- break;
- }
- }
- if (i < 12) {
- cc += wsDayNameAbbr.GetLength();
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
- CFX_WideString wsDayName;
- int32_t i = 0;
- for (; i < 7; i++) {
- pLocale->GetDayName(i, wsDayName, FALSE);
- if (wsDayName == L"") {
- continue;
- }
- if (!FXSYS_wcsncmp((const FX_WCHAR*)wsDayName, str + cc,
- wsDayName.GetLength())) {
- break;
- }
- }
- if (i < 12) {
- cc += wsDayName.GetLength();
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
- cc += 1;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
- cc += 2;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
- if (cc + 2 > len) {
- return FALSE;
- }
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- year = str[cc++] - '0';
- if (cc >= len || !FX_IsDigit(str[cc])) {
- return FALSE;
- }
- year = year * 10 + str[cc++] - '0';
- if (year <= 29) {
- year += 2000;
- } else {
- year += 1900;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
- int i = 0;
- year = 0;
- if (cc + 4 > len) {
- return FALSE;
- }
- while (i < 4) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- year = year * 10 + str[cc] - '0';
- cc++;
- i++;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
- cc += 1;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
- cc += 2;
- }
- }
- if (cc < len) {
- return FALSE;
- }
- CFX_Unitime ut;
- ut.Set(year, month, day);
- datetime = datetime + ut;
- return cc;
-}
-static void FX_ResolveZone(uint8_t& wHour,
- uint8_t& wMinute,
- FX_TIMEZONE tzDiff,
- IFX_Locale* pLocale) {
- int32_t iMinuteDiff = wHour * 60 + wMinute;
- FX_TIMEZONE tzLocale;
- pLocale->GetTimeZone(tzLocale);
- iMinuteDiff += tzLocale.tzHour * 60 +
- (tzLocale.tzHour < 0 ? -tzLocale.tzMinute : tzLocale.tzMinute);
- iMinuteDiff -= tzDiff.tzHour * 60 +
- (tzDiff.tzHour < 0 ? -tzDiff.tzMinute : tzDiff.tzMinute);
- while (iMinuteDiff > 1440) {
- iMinuteDiff -= 1440;
- }
- while (iMinuteDiff < 0) {
- iMinuteDiff += 1440;
- }
- wHour = iMinuteDiff / 60;
- wMinute = iMinuteDiff % 60;
-}
-static FX_BOOL FX_ParseLocaleTime(const CFX_WideString& wsTime,
- const CFX_WideString& wsTimePattern,
- IFX_Locale* pLocale,
- CFX_Unitime& datetime,
- int32_t& cc) {
- uint8_t hour = 0;
- uint8_t minute = 0;
- uint8_t second = 0;
- FX_WORD millisecond = 0;
- int32_t ccf = 0;
- const FX_WCHAR* str = (const FX_WCHAR*)wsTime;
- int len = wsTime.GetLength();
- const FX_WCHAR* strf = (const FX_WCHAR*)wsTimePattern;
- int lenf = wsTimePattern.GetLength();
- FX_BOOL bHasA = FALSE;
- FX_BOOL bPM = FALSE;
- while (cc < len && ccf < lenf) {
- if (strf[ccf] == '\'') {
- CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (cc + iLiteralLen > len ||
- FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
- return FALSE;
- }
- cc += iLiteralLen;
- ccf++;
- continue;
- } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) == -1) {
- if (strf[ccf] != str[cc]) {
- return FALSE;
- }
- cc++;
- ccf++;
- continue;
- }
- FX_DWORD dwSymbolNum = 1;
- FX_DWORD dwSymbol = strf[ccf++];
- while (ccf < lenf && strf[ccf] == dwSymbol) {
- ccf++;
- dwSymbolNum++;
- }
- dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
- if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1') ||
- dwSymbol == FXBSTR_ID(0, 0, 'H', '1') ||
- dwSymbol == FXBSTR_ID(0, 0, 'h', '1') ||
- dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- hour = str[cc++] - '0';
- if (cc < len && FX_IsDigit(str[cc])) {
- hour = hour * 10 + str[cc++] - '0';
- }
- if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1') && hour == 24) {
- hour = 0;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2') ||
- dwSymbol == FXBSTR_ID(0, 0, 'H', '2') ||
- dwSymbol == FXBSTR_ID(0, 0, 'h', '2') ||
- dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- hour = str[cc++] - '0';
- if (cc >= len) {
- return FALSE;
- }
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- hour = hour * 10 + str[cc++] - '0';
- if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2') && hour == 24) {
- hour = 0;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- minute = str[cc++] - '0';
- if (cc < len && FX_IsDigit(str[cc])) {
- minute = minute * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- minute = str[cc++] - '0';
- if (cc >= len) {
- return FALSE;
- }
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- minute = minute * 10 + str[cc++] - '0';
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- second = str[cc++] - '0';
- if (cc < len && FX_IsDigit(str[cc])) {
- second = second * 10 + str[cc++] - '0';
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- second = str[cc++] - '0';
- if (cc >= len) {
- return FALSE;
- }
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- second = second * 10 + str[cc++] - '0';
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
- if (cc + 3 >= len) {
- return FALSE;
- }
- int i = 0;
- while (i < 3) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- millisecond = millisecond * 10 + str[cc++] - '0';
- i++;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
- CFX_WideString wsAM;
- pLocale->GetMeridiemName(wsAM, TRUE);
- CFX_WideString wsPM;
- pLocale->GetMeridiemName(wsPM, FALSE);
- if ((cc + wsAM.GetLength() <= len) &&
- (CFX_WideStringC(str + cc, wsAM.GetLength()) == wsAM)) {
- cc += wsAM.GetLength();
- bHasA = TRUE;
- } else if ((cc + wsPM.GetLength() <= len) &&
- (CFX_WideStringC(str + cc, wsPM.GetLength()) == wsPM)) {
- cc += wsPM.GetLength();
- bHasA = TRUE;
- bPM = TRUE;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
- if (cc + 3 > len) {
- continue;
- }
- FX_DWORD dwHash = str[cc++];
- dwHash = (dwHash << 8) | str[cc++];
- dwHash = (dwHash << 8) | str[cc++];
- if (dwHash == FXBSTR_ID(0, 'G', 'M', 'T')) {
- FX_TIMEZONE tzDiff;
- tzDiff.tzHour = 0;
- tzDiff.tzMinute = 0;
- if (cc < len && (str[cc] == '-' || str[cc] == '+')) {
- cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
- }
- FX_ResolveZone(hour, minute, tzDiff, pLocale);
- } else {
- FX_LPCLOCALETIMEZONEINFO pTimeZoneInfo = NULL;
- int32_t iStart = 0, iEnd = g_iFXLocaleTimeZoneCount - 1;
- do {
- int32_t iMid = (iStart + iEnd) / 2;
- FX_LPCLOCALETIMEZONEINFO pInfo = g_FXLocaleTimeZoneData + iMid;
- if (dwHash == pInfo->uHash) {
- pTimeZoneInfo = pInfo;
- break;
- } else if (dwHash < pInfo->uHash) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- if (pTimeZoneInfo) {
- hour += pTimeZoneInfo->iHour;
- minute += pTimeZoneInfo->iHour > 0 ? pTimeZoneInfo->iMinute
- : -pTimeZoneInfo->iMinute;
- }
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
- if (str[cc] != 'Z') {
- FX_TIMEZONE tzDiff;
- cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
- FX_ResolveZone(hour, minute, tzDiff, pLocale);
- } else {
- cc++;
- }
- }
- }
- if (bHasA) {
- if (bPM) {
- hour += 12;
- if (hour == 24) {
- hour = 12;
- }
- } else {
- if (hour == 12) {
- hour = 0;
- }
- }
- }
- CFX_Unitime ut;
- ut.Set(0, 0, 0, hour, minute, second, millisecond);
- datetime = datetime + ut;
- return cc;
-}
-FX_BOOL CFX_FormatString::ParseDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- FX_DATETIMETYPE eDateTimeType,
- CFX_Unitime& dtValue) {
- dtValue.Set(0);
- if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsDatePattern, wsTimePattern;
- IFX_Locale* pLocale = NULL;
- FX_DATETIMETYPE eCategory =
- GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
- if (!pLocale) {
- return FALSE;
- }
- if (eCategory == FX_DATETIMETYPE_Unknown) {
- eCategory = eDateTimeType;
- }
- if (eCategory == FX_DATETIMETYPE_Unknown) {
- return FALSE;
- }
- if (eCategory == FX_DATETIMETYPE_TimeDate) {
- int32_t iStart = 0;
- if (!FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue,
- iStart)) {
- return FALSE;
- }
- if (!FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue,
- iStart)) {
- return FALSE;
- }
- } else {
- int32_t iStart = 0;
- if ((eCategory & FX_DATETIMETYPE_Date) &&
- !FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue,
- iStart)) {
- return FALSE;
- }
- if ((eCategory & FX_DATETIMETYPE_Time) &&
- !FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue,
- iStart)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_FormatString::ParseZero(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern) {
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
- int32_t iText = 0, iPattern = 0;
- const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
- int32_t iLenText = wsSrcText.GetLength();
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern && iText < iLenText) {
- if (pStrPattern[iPattern] == '\'') {
- CFX_WideString wsLiteral =
- FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (iText + iLiteralLen > iLenText ||
- FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- return FALSE;
- }
- iText += iLiteralLen;
- iPattern++;
- continue;
- } else if (pStrPattern[iPattern] != pStrText[iText]) {
- return FALSE;
- } else {
- iText++;
- iPattern++;
- }
- }
- return iPattern == iLenPattern && iText == iLenText;
-}
-FX_BOOL CFX_FormatString::ParseNull(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern) {
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
- int32_t iText = 0, iPattern = 0;
- const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
- int32_t iLenText = wsSrcText.GetLength();
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern && iText < iLenText) {
- if (pStrPattern[iPattern] == '\'') {
- CFX_WideString wsLiteral =
- FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
- if (iText + iLiteralLen > iLenText ||
- FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
- iLiteralLen)) {
- return FALSE;
- }
- iText += iLiteralLen;
- iPattern++;
- continue;
- } else if (pStrPattern[iPattern] != pStrText[iText]) {
- return FALSE;
- } else {
- iText++;
- iPattern++;
- }
- }
- return iPattern == iLenPattern && iText == iLenText;
-}
-FX_BOOL CFX_FormatString::FormatText(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsPattern.IsEmpty()) {
- return FALSE;
- }
- int32_t iLenText = wsSrcText.GetLength();
- if (iLenText == 0) {
- return FALSE;
- }
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
- int32_t iText = 0, iPattern = 0;
- const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern) {
- switch (pStrPattern[iPattern]) {
- case '\'': {
- wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- iPattern++;
- break;
- }
- case 'A':
- if (iText >= iLenText || !FX_IsAlpha(pStrText[iText])) {
- return FALSE;
- }
- wsOutput += pStrText[iText++];
- iPattern++;
- break;
- case 'X':
- if (iText >= iLenText) {
- return FALSE;
- }
- wsOutput += pStrText[iText++];
- iPattern++;
- break;
- case 'O':
- case '0':
- if (iText >= iLenText ||
- (!FX_IsDigit(pStrText[iText]) && !FX_IsAlpha(pStrText[iText]))) {
- return FALSE;
- }
- wsOutput += pStrText[iText++];
- iPattern++;
- break;
- case '9':
- if (iText >= iLenText || !FX_IsDigit(pStrText[iText])) {
- return FALSE;
- }
- wsOutput += pStrText[iText++];
- iPattern++;
- break;
- default:
- wsOutput += pStrPattern[iPattern++];
- break;
- }
- }
- return iText == iLenText;
-}
-static int32_t FX_GetNumTrailingLimit(const CFX_WideString& wsFormat,
- int iDotPos,
- FX_BOOL& bTrimTailZeros) {
- if (iDotPos < 0) {
- return 0;
- }
- int32_t iCount = wsFormat.GetLength();
- int32_t iTreading = 0;
- for (iDotPos++; iDotPos < iCount; iDotPos++) {
- FX_WCHAR wc = wsFormat[iDotPos];
- if (wc == L'z' || wc == L'9' || wc == 'Z') {
- iTreading++;
- bTrimTailZeros = (wc == L'9' ? FALSE : TRUE);
- }
- }
- return iTreading;
-}
-FX_BOOL CFX_FormatString::FormatStrNum(const CFX_WideStringC& wsInputNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsInputNum.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- int32_t dot_index_f = -1;
- FX_DWORD dwNumStyle = 0;
- CFX_WideString wsNumFormat;
- IFX_Locale* pLocale =
- GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
- if (!pLocale || wsNumFormat.IsEmpty()) {
- return FALSE;
- }
- int32_t cc = 0, ccf = 0;
- const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
- int lenf = wsNumFormat.GetLength();
- CFX_WideString wsSrcNum = wsInputNum;
- wsSrcNum.TrimLeft('0');
- if (wsSrcNum.IsEmpty() || wsSrcNum[0] == '.') {
- wsSrcNum.Insert(0, '0');
- }
- CFX_Decimal decimal = CFX_Decimal(wsSrcNum);
- if (dwNumStyle & FX_NUMSTYLE_Percent) {
- decimal = decimal * CFX_Decimal(100);
- wsSrcNum = decimal;
- }
- int32_t exponent = 0;
- if (dwNumStyle & FX_NUMSTYLE_Exponent) {
- int fixed_count = 0;
- while (ccf < dot_index_f) {
- switch (strf[ccf]) {
- case '\'':
- FX_GetLiteralText(strf, ccf, dot_index_f);
- break;
- case '9':
- case 'z':
- case 'Z':
- fixed_count++;
- break;
- }
- ccf++;
- }
- int threshold = 1;
- while (fixed_count > 1) {
- threshold *= 10;
- fixed_count--;
- }
- if (decimal != CFX_Decimal(0)) {
- if (decimal < CFX_Decimal(threshold)) {
- decimal = decimal * CFX_Decimal(10);
- exponent = -1;
- while (decimal < CFX_Decimal(threshold)) {
- decimal = decimal * CFX_Decimal(10);
- exponent -= 1;
- }
- } else if (decimal > CFX_Decimal(threshold)) {
- threshold *= 10;
- while (decimal > CFX_Decimal(threshold)) {
- decimal = decimal / CFX_Decimal(10);
- exponent += 1;
- }
- }
- }
- }
- FX_BOOL bTrimTailZeros = FALSE;
- int32_t iTreading =
- FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
- int32_t scale = decimal.GetScale();
- if (iTreading < scale) {
- decimal.SetScale(iTreading);
- wsSrcNum = decimal;
- }
- if (bTrimTailZeros && scale > 0 && iTreading > 0) {
- wsSrcNum.TrimRight(L"0");
- wsSrcNum.TrimRight(L".");
- }
- CFX_WideString wsGroupSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
- FX_BOOL bNeg = FALSE;
- if (wsSrcNum[0] == '-') {
- bNeg = TRUE;
- wsSrcNum.Delete(0, 1);
- }
- FX_BOOL bAddNeg = FALSE;
- const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
- int len = wsSrcNum.GetLength();
- int dot_index = wsSrcNum.Find('.');
- if (dot_index == -1) {
- dot_index = len;
- }
- ccf = dot_index_f - 1;
- cc = dot_index - 1;
- while (ccf >= 0) {
- switch (strf[ccf]) {
- case '9':
- if (cc >= 0) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- cc--;
- } else {
- wsOutput = CFX_WideStringC(L'0') + wsOutput;
- }
- ccf--;
- break;
- case 'z':
- if (cc >= 0) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- if (str[0] != '0') {
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- }
- cc--;
- }
- ccf--;
- break;
- case 'Z':
- if (cc >= 0) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- if (str[0] == '0') {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- } else {
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- }
- cc--;
- } else {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- }
- ccf--;
- break;
- case 'S':
- if (bNeg) {
- CFX_WideString wsMinusSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
- wsOutput = wsMinusSymbol + wsOutput;
- bAddNeg = TRUE;
- } else {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- }
- ccf--;
- break;
- case 's':
- if (bNeg) {
- CFX_WideString wsMinusSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
- wsOutput = wsMinusSymbol + wsOutput;
- bAddNeg = TRUE;
- }
- ccf--;
- break;
- case 'E': {
- CFX_WideString wsExp;
- wsExp.Format(L"E%+d", exponent);
- wsOutput = wsExp + wsOutput;
- }
- ccf--;
- break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- wsOutput = wsSymbol + wsOutput;
- }
- ccf--;
- break;
- case 'r':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
- if (bNeg) {
- wsOutput = L"CR" + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'R':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
- if (bNeg) {
- wsOutput = L"CR" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'b':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
- if (bNeg) {
- wsOutput = L"db" + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'B':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
- if (bNeg) {
- wsOutput = L"DB" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- wsOutput = wsSymbol + wsOutput;
- }
- ccf--;
- break;
- case ',':
- if (cc >= 0) {
- wsOutput = wsGroupSymbol + wsOutput;
- }
- ccf--;
- break;
- case '(':
- if (bNeg) {
- wsOutput = L"(" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- bAddNeg = TRUE;
- ccf--;
- break;
- case ')':
- if (bNeg) {
- wsOutput = L")" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf--;
- break;
- case '\'':
- wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
- ccf--;
- break;
- default:
- wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
- ccf--;
- }
- }
- if (cc >= 0) {
- int nPos = dot_index % 3;
- wsOutput.Empty();
- for (int32_t i = 0; i < dot_index; i++) {
- if (i % 3 == nPos && i != 0) {
- wsOutput += wsGroupSymbol;
- }
- wsOutput += wsSrcNum[i];
- }
- if (dot_index < len) {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
- wsOutput += wsSymbol;
- wsOutput += wsSrcNum.Right(len - dot_index - 1);
- }
- if (bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput = wsMinusymbol + wsOutput;
- }
- return FALSE;
- }
- if (dot_index_f == wsNumFormat.GetLength()) {
- if (!bAddNeg && bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput = wsMinusymbol + wsOutput;
- }
- return TRUE;
- }
- CFX_WideString wsDotSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
- if (strf[dot_index_f] == 'V') {
- wsOutput += wsDotSymbol;
- } else if (strf[dot_index_f] == '.') {
- if (dot_index < len) {
- wsOutput += wsDotSymbol;
- } else {
- if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
- wsOutput += wsDotSymbol;
- }
- }
- }
- ccf = dot_index_f + 1;
- cc = dot_index + 1;
- while (ccf < lenf) {
- switch (strf[ccf]) {
- case '\'':
- wsOutput += FX_GetLiteralText(strf, ccf, lenf);
- ccf++;
- break;
- case '9':
- if (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wsOutput += str[cc];
- cc++;
- } else {
- wsOutput += L'0';
- }
- ccf++;
- break;
- case 'z':
- if (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wsOutput += str[cc];
- cc++;
- }
- ccf++;
- break;
- case 'Z':
- if (cc < len) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wsOutput += str[cc];
- cc++;
- } else {
- wsOutput += L'0';
- }
- ccf++;
- break;
- case 'E': {
- CFX_WideString wsExp;
- wsExp.Format(L"E%+d", exponent);
- wsOutput += wsExp;
- }
- ccf++;
- break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- wsOutput += wsSymbol;
- }
- ccf++;
- break;
- case 'c':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
- if (bNeg) {
- wsOutput += L"CR";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'C':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
- if (bNeg) {
- wsOutput += L"CR";
- } else {
- wsOutput += L" ";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'd':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
- if (bNeg) {
- wsOutput += L"db";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'D':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
- if (bNeg) {
- wsOutput += L"DB";
- } else {
- wsOutput += L" ";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- wsOutput += wsSymbol;
- }
- ccf++;
- break;
- case '8': {
- while (ccf < lenf && strf[ccf] == '8') {
- ccf++;
- }
- while (cc < len && FX_IsDigit(str[cc])) {
- wsOutput += str[cc];
- cc++;
- }
- } break;
- case ',':
- wsOutput += wsGroupSymbol;
- ccf++;
- break;
- case '(':
- if (bNeg) {
- wsOutput += '(';
- } else {
- wsOutput += ' ';
- }
- bAddNeg = TRUE;
- ccf++;
- break;
- case ')':
- if (bNeg) {
- wsOutput += ')';
- } else {
- wsOutput += ' ';
- }
- ccf++;
- break;
- default:
- ccf++;
- }
- }
- if (!bAddNeg && bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput =
- wsMinusymbol + wsOutput[0] + wsOutput.Mid(1, wsOutput.GetLength() - 1);
- }
- return TRUE;
-}
-FX_BOOL CFX_FormatString::FormatLCNumeric(CFX_LCNumeric& lcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- int32_t dot_index_f = -1;
- FX_DWORD dwNumStyle = 0;
- CFX_WideString wsNumFormat;
- IFX_Locale* pLocale =
- GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
- if (!pLocale || wsNumFormat.IsEmpty()) {
- return FALSE;
- }
- int32_t cc = 0, ccf = 0;
- const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
- int lenf = wsNumFormat.GetLength();
- double dbOrgRaw = lcNum.GetDouble();
- double dbRetValue = dbOrgRaw;
- if (dwNumStyle & FX_NUMSTYLE_Percent) {
- dbRetValue *= 100;
- }
- int32_t exponent = 0;
- if (dwNumStyle & FX_NUMSTYLE_Exponent) {
- int fixed_count = 0;
- while (ccf < dot_index_f) {
- switch (strf[ccf]) {
- case '\'':
- FX_GetLiteralText(strf, ccf, dot_index_f);
- break;
- case '9':
- case 'z':
- case 'Z':
- fixed_count++;
- break;
- }
- ccf++;
- }
- int threshold = 1;
- while (fixed_count > 1) {
- threshold *= 10;
- fixed_count--;
- }
- if (dbRetValue != 0) {
- if (dbRetValue < threshold) {
- dbRetValue *= 10;
- exponent = -1;
- while (dbRetValue < threshold) {
- dbRetValue *= 10;
- exponent -= 1;
- }
- } else if (dbRetValue > threshold) {
- threshold *= 10;
- while (dbRetValue > threshold) {
- dbRetValue /= 10;
- exponent += 1;
- }
- }
- }
- }
- if (dwNumStyle & (FX_NUMSTYLE_Percent | FX_NUMSTYLE_Exponent)) {
- lcNum = CFX_LCNumeric(dbRetValue);
- }
- FX_BOOL bTrimTailZeros = FALSE;
- int32_t iTreading =
- FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
- CFX_WideString wsNumeric = lcNum.ToString(iTreading, bTrimTailZeros);
- if (wsNumeric.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsGroupSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
- FX_BOOL bNeg = FALSE;
- if (wsNumeric[0] == '-') {
- bNeg = TRUE;
- wsNumeric.Delete(0, 1);
- }
- FX_BOOL bAddNeg = FALSE;
- const FX_WCHAR* str = (const FX_WCHAR*)wsNumeric;
- int len = wsNumeric.GetLength();
- int dot_index = wsNumeric.Find('.');
- if (dot_index == -1) {
- dot_index = len;
- }
- ccf = dot_index_f - 1;
- cc = dot_index - 1;
- while (ccf >= 0) {
- switch (strf[ccf]) {
- case '9':
- if (cc >= 0) {
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- cc--;
- } else {
- wsOutput = CFX_WideStringC(L'0') + wsOutput;
- }
- ccf--;
- break;
- case 'z':
- if (cc >= 0) {
- if (lcNum.m_Integral != 0) {
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- }
- cc--;
- }
- ccf--;
- break;
- case 'Z':
- if (cc >= 0) {
- if (lcNum.m_Integral == 0) {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- } else {
- wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
- }
- cc--;
- } else {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- }
- ccf--;
- break;
- case 'S':
- if (bNeg) {
- CFX_WideString wsMinusSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
- wsOutput = wsMinusSymbol + wsOutput;
- bAddNeg = TRUE;
- } else {
- wsOutput = CFX_WideStringC(L' ') + wsOutput;
- }
- ccf--;
- break;
- case 's':
- if (bNeg) {
- CFX_WideString wsMinusSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
- wsOutput = wsMinusSymbol + wsOutput;
- bAddNeg = TRUE;
- }
- ccf--;
- break;
- case 'E': {
- CFX_WideString wsExp;
- wsExp.Format(L"E%+d", exponent);
- wsOutput = wsExp + wsOutput;
- }
- ccf--;
- break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- wsOutput = wsSymbol + wsOutput;
- }
- ccf--;
- break;
- case 'r':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
- if (bNeg) {
- wsOutput = L"CR" + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'R':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
- if (bNeg) {
- wsOutput = L"CR" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'b':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
- if (bNeg) {
- wsOutput = L"db" + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case 'B':
- if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
- if (bNeg) {
- wsOutput = L"DB" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf -= 2;
- bAddNeg = TRUE;
- }
- break;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- wsOutput = wsSymbol + wsOutput;
- }
- ccf--;
- break;
- case ',':
- if (cc >= 0) {
- wsOutput = wsGroupSymbol + wsOutput;
- }
- ccf--;
- break;
- case '(':
- if (bNeg) {
- wsOutput = L"(" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- bAddNeg = TRUE;
- ccf--;
- break;
- case ')':
- if (bNeg) {
- wsOutput = L")" + wsOutput;
- } else {
- wsOutput = L" " + wsOutput;
- }
- ccf--;
- break;
- case '\'':
- wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
- ccf--;
- break;
- default:
- wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
- ccf--;
- }
- }
- if (cc >= 0) {
- int nPos = dot_index % 3;
- wsOutput.Empty();
- for (int32_t i = 0; i < dot_index; i++) {
- if (i % 3 == nPos && i != 0) {
- wsOutput += wsGroupSymbol;
- }
- wsOutput += wsNumeric[i];
- }
- if (dot_index < len) {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
- wsOutput += wsSymbol;
- wsOutput += wsNumeric.Right(len - dot_index - 1);
- }
- if (bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput = wsMinusymbol + wsOutput;
- }
- return FALSE;
- }
- if (dot_index_f == wsNumFormat.GetLength()) {
- if (!bAddNeg && bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput = wsMinusymbol + wsOutput;
- }
- return TRUE;
- }
- CFX_WideString wsDotSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
- if (strf[dot_index_f] == 'V') {
- wsOutput += wsDotSymbol;
- } else if (strf[dot_index_f] == '.') {
- if (dot_index < len) {
- wsOutput += wsDotSymbol;
- } else {
- if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
- wsOutput += wsDotSymbol;
- }
- }
- }
- ccf = dot_index_f + 1;
- cc = dot_index + 1;
- while (ccf < lenf) {
- switch (strf[ccf]) {
- case '\'':
- wsOutput += FX_GetLiteralText(strf, ccf, lenf);
- ccf++;
- break;
- case '9':
- if (cc < len) {
- wsOutput += str[cc];
- cc++;
- } else {
- wsOutput += L'0';
- }
- ccf++;
- break;
- case 'z':
- if (cc < len) {
- wsOutput += str[cc];
- cc++;
- }
- ccf++;
- break;
- case 'Z':
- if (cc < len) {
- wsOutput += str[cc];
- cc++;
- } else {
- wsOutput += L'0';
- }
- ccf++;
- break;
- case 'E': {
- CFX_WideString wsExp;
- wsExp.Format(L"E%+d", exponent);
- wsOutput += wsExp;
- }
- ccf++;
- break;
- case '$': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
- wsOutput += wsSymbol;
- }
- ccf++;
- break;
- case 'c':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
- if (bNeg) {
- wsOutput += L"CR";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'C':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
- if (bNeg) {
- wsOutput += L"CR";
- } else {
- wsOutput += L" ";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'd':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
- if (bNeg) {
- wsOutput += L"db";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case 'D':
- if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
- if (bNeg) {
- wsOutput += L"DB";
- } else {
- wsOutput += L" ";
- }
- ccf += 2;
- bAddNeg = TRUE;
- }
- break;
- case '%': {
- CFX_WideString wsSymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
- wsOutput += wsSymbol;
- }
- ccf++;
- break;
- case '8': {
- while (ccf < lenf && strf[ccf] == '8') {
- ccf++;
- }
- while (cc < len && FX_IsDigit(str[cc])) {
- wsOutput += str[cc];
- cc++;
- }
- } break;
- case ',':
- wsOutput += wsGroupSymbol;
- ccf++;
- break;
- case '(':
- if (bNeg) {
- wsOutput += '(';
- } else {
- wsOutput += ' ';
- }
- bAddNeg = TRUE;
- ccf++;
- break;
- case ')':
- if (bNeg) {
- wsOutput += ')';
- } else {
- wsOutput += ' ';
- }
- ccf++;
- break;
- default:
- ccf++;
- }
- }
- if (!bAddNeg && bNeg) {
- CFX_WideString wsMinusymbol;
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
- wsOutput =
- wsOutput[0] + wsMinusymbol + wsOutput.Mid(1, wsOutput.GetLength() - 1);
- }
- return TRUE;
-}
-FX_BOOL CFX_FormatString::FormatNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- return FormatStrNum(wsSrcNum, wsPattern, wsOutput);
-}
-FX_BOOL CFX_FormatString::FormatNum(FX_FLOAT fNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_LCNumeric lcNum(fNum);
- return FormatLCNumeric(lcNum, wsPattern, wsOutput);
-}
-FX_BOOL FX_DateFromCanonical(const CFX_WideString& wsDate,
- CFX_Unitime& datetime) {
- int32_t year = 1900;
- int32_t month = 1;
- int32_t day = 1;
- FX_WORD wYear = 0;
- int cc_start = 0, cc = 0;
- const FX_WCHAR* str = (const FX_WCHAR*)wsDate;
- int len = wsDate.GetLength();
- if (len > 10) {
- return FALSE;
- }
- while (cc < len && cc < 4) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- wYear = wYear * 10 + str[cc++] - '0';
- }
- year = wYear;
- if (cc < 4 || wYear < 1900) {
- return FALSE;
- }
- if (cc < len) {
- if (str[cc] == '-') {
- cc++;
- }
- cc_start = cc;
- uint8_t tmpM = 0;
- while (cc < len && cc < cc_start + 2) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- tmpM = tmpM * 10 + str[cc++] - '0';
- }
- month = tmpM;
- if (cc == cc_start + 1 || tmpM > 12 || tmpM < 1) {
- return FALSE;
- }
- if (cc < len) {
- if (str[cc] == '-') {
- cc++;
- }
- uint8_t tmpD = 0;
- cc_start = cc;
- while (cc < len && cc < cc_start + 2) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- tmpD = tmpD * 10 + str[cc++] - '0';
- }
- day = tmpD;
- if (tmpD < 1) {
- return FALSE;
- }
- if ((tmpM == 1 || tmpM == 3 || tmpM == 5 || tmpM == 7 || tmpM == 8 ||
- tmpM == 10 || tmpM == 12) &&
- tmpD > 31) {
- return FALSE;
- }
- if ((tmpM == 4 || tmpM == 6 || tmpM == 9 || tmpM == 11) && tmpD > 30) {
- return FALSE;
- }
- FX_BOOL iLeapYear;
- if ((wYear % 4 == 0 && wYear % 100 != 0) || wYear % 400 == 0) {
- iLeapYear = TRUE;
- } else {
- iLeapYear = FALSE;
- }
- if ((iLeapYear && tmpM == 2 && tmpD > 29) ||
- (!iLeapYear && tmpM == 2 && tmpD > 28)) {
- return FALSE;
- }
- }
- }
- CFX_Unitime ut;
- ut.Set(year, month, day);
- datetime = datetime + ut;
- return TRUE;
-}
-FX_BOOL FX_TimeFromCanonical(const CFX_WideStringC& wsTime,
- CFX_Unitime& datetime,
- IFX_Locale* pLocale) {
- if (wsTime.GetLength() == 0) {
- return FALSE;
- }
- uint8_t hour = 0;
- uint8_t minute = 0;
- uint8_t second = 0;
- FX_WORD millisecond = 0;
- int cc_start = 0, cc = cc_start;
- const FX_WCHAR* str = (const FX_WCHAR*)wsTime.GetPtr();
- int len = wsTime.GetLength();
- while (cc < len && cc < 2) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- hour = hour * 10 + str[cc++] - '0';
- }
- if (cc < 2 || hour >= 24) {
- return FALSE;
- }
- if (cc < len) {
- if (str[cc] == ':') {
- cc++;
- }
- cc_start = cc;
- while (cc < len && cc < cc_start + 2) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- minute = minute * 10 + str[cc++] - '0';
- }
- if (cc == cc_start + 1 || minute >= 60) {
- return FALSE;
- }
- if (cc < len) {
- if (str[cc] == ':') {
- cc++;
- }
- cc_start = cc;
- while (cc < len && cc < cc_start + 2) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- second = second * 10 + str[cc++] - '0';
- }
- if (cc == cc_start + 1 || second >= 60) {
- return FALSE;
- }
- if (cc < len) {
- if (str[cc] == '.') {
- cc++;
- cc_start = cc;
- while (cc < len && cc < cc_start + 3) {
- if (!FX_IsDigit(str[cc])) {
- return FALSE;
- }
- millisecond = millisecond * 10 + str[cc++] - '0';
- }
- if (cc < cc_start + 3 || millisecond >= 1000) {
- return FALSE;
- }
- }
- if (cc < len) {
- FX_TIMEZONE tzDiff;
- tzDiff.tzHour = 0;
- tzDiff.tzMinute = 0;
- if (str[cc] != 'Z') {
- cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
- }
- FX_ResolveZone(hour, minute, tzDiff, pLocale);
- }
- }
- }
- }
- CFX_Unitime ut;
- ut.Set(0, 0, 0, hour, minute, second, millisecond);
- datetime = datetime + ut;
- return TRUE;
-}
-static FX_WORD FX_GetSolarMonthDays(FX_WORD year, FX_WORD month) {
- if (month % 2) {
- return 31;
- } else if (month == 2) {
- return FX_IsLeapYear(year) ? 29 : 28;
- }
- return 30;
-}
-static FX_WORD FX_GetWeekDay(FX_WORD year, FX_WORD month, FX_WORD day) {
- FX_WORD g_month_day[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
- FX_WORD nDays =
- (year - 1) % 7 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
- nDays += g_month_day[month - 1] + day;
- if (FX_IsLeapYear(year) && month > 2) {
- nDays++;
- }
- return nDays % 7;
-}
-static FX_WORD FX_GetWeekOfMonth(FX_WORD year, FX_WORD month, FX_WORD day) {
- FX_WORD week_day = FX_GetWeekDay(year, month, 1);
- FX_WORD week_index = 0;
- week_index += day / 7;
- day = day % 7;
- if (week_day + day > 7) {
- week_index++;
- }
- return week_index;
-}
-static FX_WORD FX_GetWeekOfYear(FX_WORD year, FX_WORD month, FX_WORD day) {
- FX_WORD nDays = 0;
- for (FX_WORD i = 1; i < month; i++) {
- nDays += FX_GetSolarMonthDays(year, i);
- }
- nDays += day;
- FX_WORD week_day = FX_GetWeekDay(year, 1, 1);
- FX_WORD week_index = 1;
- week_index += nDays / 7;
- nDays = nDays % 7;
- if (week_day + nDays > 7) {
- week_index++;
- }
- return week_index;
-}
-static FX_BOOL FX_DateFormat(const CFX_WideString& wsDatePattern,
- IFX_Locale* pLocale,
- const CFX_Unitime& datetime,
- CFX_WideString& wsResult) {
- FX_BOOL bRet = TRUE;
- int32_t year = datetime.GetYear();
- uint8_t month = datetime.GetMonth();
- uint8_t day = datetime.GetDay();
- int32_t ccf = 0;
- const FX_WCHAR* strf = (const FX_WCHAR*)wsDatePattern;
- int32_t lenf = wsDatePattern.GetLength();
- while (ccf < lenf) {
- if (strf[ccf] == '\'') {
- wsResult += FX_GetLiteralText(strf, ccf, lenf);
- ccf++;
- continue;
- } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
- wsResult += strf[ccf++];
- continue;
- }
- FX_DWORD dwSymbolNum = 1;
- FX_DWORD dwSymbol = strf[ccf++];
- while (ccf < lenf && strf[ccf] == dwSymbol) {
- ccf++;
- dwSymbolNum++;
- }
- dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
- if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
- CFX_WideString wsDay;
- wsDay.Format(L"%d", day);
- wsResult += wsDay;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
- CFX_WideString wsDay;
- wsDay.Format(L"%02d", day);
- wsResult += wsDay;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
- FX_WORD nDays = 0;
- for (int i = 1; i < month; i++) {
- nDays += FX_GetSolarMonthDays(year, i);
- }
- nDays += day;
- CFX_WideString wsDays;
- wsDays.Format(L"%d", nDays);
- wsResult += wsDays;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
- FX_WORD nDays = 0;
- for (int i = 1; i < month; i++) {
- nDays += FX_GetSolarMonthDays(year, i);
- }
- nDays += day;
- CFX_WideString wsDays;
- wsDays.Format(L"%03d", nDays);
- wsResult += wsDays;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
- CFX_WideString wsMonth;
- wsMonth.Format(L"%d", month);
- wsResult += wsMonth;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
- CFX_WideString wsMonth;
- wsMonth.Format(L"%02d", month);
- wsResult += wsMonth;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
- CFX_WideString wsTemp;
- pLocale->GetMonthName(month - 1, wsTemp, TRUE);
- wsResult += wsTemp;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
- CFX_WideString wsTemp;
- pLocale->GetMonthName(month - 1, wsTemp, FALSE);
- wsResult += wsTemp;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
- FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
- CFX_WideString wsWeekDay;
- wsWeekDay.Format(L"%d", wWeekDay + 1);
- wsResult += wsWeekDay;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
- FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
- CFX_WideString wsTemp;
- pLocale->GetDayName(wWeekDay, wsTemp, TRUE);
- wsResult += wsTemp;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
- FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
- if (pLocale) {
- CFX_WideString wsTemp;
- pLocale->GetDayName(wWeekDay, wsTemp, FALSE);
- wsResult += wsTemp;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
- FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
- CFX_WideString wsWeekDay;
- wsWeekDay.Format(L"%d", wWeekDay ? wWeekDay : 7);
- wsResult += wsWeekDay;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
- CFX_WideString wsTemp;
- pLocale->GetEraName(wsTemp, year < 0);
- wsResult += wsTemp;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
- CFX_WideString wsYear;
- wsYear.Format(L"%02d", year % 100);
- wsResult += wsYear;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
- CFX_WideString wsYear;
- wsYear.Format(L"%d", year);
- wsResult += wsYear;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
- FX_WORD week_index = FX_GetWeekOfMonth(year, month, day);
- CFX_WideString wsWeekInMonth;
- wsWeekInMonth.Format(L"%d", week_index);
- wsResult += wsWeekInMonth;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
- FX_WORD week_index = FX_GetWeekOfYear(year, month, day);
- CFX_WideString wsWeekInYear;
- wsWeekInYear.Format(L"%02d", week_index);
- wsResult += wsWeekInYear;
- }
- }
- return bRet;
-}
-static FX_BOOL FX_TimeFormat(const CFX_WideString& wsTimePattern,
- IFX_Locale* pLocale,
- const CFX_Unitime& datetime,
- CFX_WideString& wsResult) {
- FX_BOOL bGMT = FALSE;
- FX_BOOL bRet = TRUE;
- uint8_t hour = datetime.GetHour();
- uint8_t minute = datetime.GetMinute();
- uint8_t second = datetime.GetSecond();
- FX_WORD millisecond = datetime.GetMillisecond();
- int32_t ccf = 0;
- const FX_WCHAR* strf = (const FX_WCHAR*)wsTimePattern;
- int32_t lenf = wsTimePattern.GetLength();
- FX_WORD wHour = hour;
- FX_BOOL bPM = FALSE;
- if (wsTimePattern.Find('A') != -1) {
- if (wHour >= 12) {
- bPM = TRUE;
- }
- }
- while (ccf < lenf) {
- if (strf[ccf] == '\'') {
- wsResult += FX_GetLiteralText(strf, ccf, lenf);
- ccf++;
- continue;
- } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) < 0) {
- wsResult += strf[ccf++];
- continue;
- }
- FX_DWORD dwSymbolNum = 1;
- FX_DWORD dwSymbol = strf[ccf++];
- while (ccf < lenf && strf[ccf] == dwSymbol) {
- ccf++;
- dwSymbolNum++;
- }
- dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
- if (dwSymbol == FXBSTR_ID(0, 0, 'h', '1')) {
- if (wHour > 12) {
- wHour -= 12;
- }
- CFX_WideString wsHour;
- wsHour.Format(L"%d", wHour == 0 ? 12 : wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'h', '2')) {
- if (wHour > 12) {
- wHour -= 12;
- }
- CFX_WideString wsHour;
- wsHour.Format(L"%02d", wHour == 0 ? 12 : wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
- CFX_WideString wsHour;
- wsHour.Format(L"%d", wHour == 0 ? 24 : wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
- CFX_WideString wsHour;
- wsHour.Format(L"%02d", wHour == 0 ? 24 : wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1')) {
- if (wHour > 12) {
- wHour -= 12;
- }
- CFX_WideString wsHour;
- wsHour.Format(L"%d", wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '1')) {
- CFX_WideString wsHour;
- wsHour.Format(L"%d", wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2')) {
- if (wHour > 12) {
- wHour -= 12;
- }
- CFX_WideString wsHour;
- wsHour.Format(L"%02d", wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '2')) {
- CFX_WideString wsHour;
- wsHour.Format(L"%02d", wHour);
- wsResult += wsHour;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
- CFX_WideString wsMinute;
- wsMinute.Format(L"%d", minute);
- wsResult += wsMinute;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
- CFX_WideString wsMinute;
- wsMinute.Format(L"%02d", minute);
- wsResult += wsMinute;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
- CFX_WideString wsSecond;
- wsSecond.Format(L"%d", second);
- wsResult += wsSecond;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
- CFX_WideString wsSecond;
- wsSecond.Format(L"%02d", second);
- wsResult += wsSecond;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
- CFX_WideString wsMilliseconds;
- wsMilliseconds.Format(L"%03d", millisecond);
- wsResult += wsMilliseconds;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
- CFX_WideString wsMeridiem;
- pLocale->GetMeridiemName(wsMeridiem, !bPM);
- wsResult += wsMeridiem;
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
- wsResult += FX_WSTRC(L"GMT");
- FX_TIMEZONE tz;
- pLocale->GetTimeZone(tz);
- if (!bGMT && (tz.tzHour != 0 || tz.tzMinute != 0)) {
- if (tz.tzHour < 0) {
- wsResult += FX_WSTRC(L"-");
- } else {
- wsResult += FX_WSTRC(L"+");
- }
- CFX_WideString wsTimezone;
- wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
- wsResult += wsTimezone;
- }
- } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
- FX_TIMEZONE tz;
- pLocale->GetTimeZone(tz);
- if (!bGMT && tz.tzHour != 0 && tz.tzMinute != 0) {
- if (tz.tzHour < 0) {
- wsResult += FX_WSTRC(L"-");
- } else {
- wsResult += FX_WSTRC(L"+");
- }
- CFX_WideString wsTimezone;
- wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
- wsResult += wsTimezone;
- }
- }
- }
- return bRet;
-}
-static FX_BOOL FX_FormatDateTime(const CFX_Unitime& dt,
- const CFX_WideString& wsDatePattern,
- const CFX_WideString& wsTimePattern,
- FX_BOOL bDateFirst,
- IFX_Locale* pLocale,
- CFX_WideString& wsOutput) {
- FX_BOOL bRet = TRUE;
- CFX_WideString wsDateOut, wsTimeOut;
- if (!wsDatePattern.IsEmpty()) {
- bRet &= FX_DateFormat(wsDatePattern, pLocale, dt, wsDateOut);
- }
- if (!wsTimePattern.IsEmpty()) {
- bRet &= FX_TimeFormat(wsTimePattern, pLocale, dt, wsTimeOut);
- }
- wsOutput = bDateFirst ? wsDateOut + wsTimeOut : wsTimeOut + wsDateOut;
- return bRet;
-}
-FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsDatePattern, wsTimePattern;
- IFX_Locale* pLocale = NULL;
- FX_DATETIMETYPE eCategory =
- GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
- if (pLocale == NULL || eCategory == FX_DATETIMETYPE_Unknown) {
- return FALSE;
- }
- CFX_Unitime dt(0);
- int32_t iT = wsSrcDateTime.Find(L"T");
- if (iT < 0) {
- if (eCategory == FX_DATETIMETYPE_Date) {
- FX_DateFromCanonical(wsSrcDateTime, dt);
- } else if (eCategory == FX_DATETIMETYPE_Time) {
- FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale);
- }
- } else {
- FX_DateFromCanonical(wsSrcDateTime.Left(iT), dt);
- FX_TimeFromCanonical(
- wsSrcDateTime.Right(wsSrcDateTime.GetLength() - iT - 1), dt, pLocale);
- }
- return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern,
- eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
- wsOutput);
-}
-FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput,
- FX_DATETIMETYPE eDateTimeType) {
- if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsDatePattern, wsTimePattern;
- IFX_Locale* pLocale = NULL;
- FX_DATETIMETYPE eCategory =
- GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
- if (!pLocale) {
- return FALSE;
- }
- if (eCategory == FX_DATETIMETYPE_Unknown) {
- if (eDateTimeType == FX_DATETIMETYPE_Time) {
- wsTimePattern = wsDatePattern;
- wsDatePattern.Empty();
- }
- eCategory = eDateTimeType;
- }
- if (eCategory == FX_DATETIMETYPE_Unknown) {
- return FALSE;
- }
- CFX_Unitime dt(0);
- int32_t iT = wsSrcDateTime.Find(L"T");
- if (iT < 0) {
- if (eCategory == FX_DATETIMETYPE_Date &&
- FX_DateFromCanonical(wsSrcDateTime, dt)) {
- return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale,
- wsOutput);
- } else if (eCategory == FX_DATETIMETYPE_Time &&
- FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale)) {
- return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale,
- wsOutput);
- }
- } else {
- CFX_WideStringC wsSrcDate((const FX_WCHAR*)wsSrcDateTime, iT);
- CFX_WideStringC wsSrcTime((const FX_WCHAR*)wsSrcDateTime + iT + 1,
- wsSrcDateTime.GetLength() - iT - 1);
- if (wsSrcDate.IsEmpty() || wsSrcTime.IsEmpty()) {
- return FALSE;
- }
- if (FX_DateFromCanonical(wsSrcDate, dt) &&
- FX_TimeFromCanonical(wsSrcTime, dt, pLocale)) {
- return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern,
- eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
- wsOutput);
- }
- }
- return FALSE;
-}
-FX_BOOL CFX_FormatString::FormatDateTime(const CFX_Unitime& dt,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsDatePattern, wsTimePattern;
- IFX_Locale* pLocale = NULL;
- FX_DATETIMETYPE eCategory =
- GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
- if (!pLocale) {
- return FALSE;
- }
- return FX_FormatDateTime(dt, wsPattern, wsTimePattern,
- eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
- wsOutput);
-}
-FX_BOOL CFX_FormatString::FormatZero(const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
- int32_t iPattern = 0;
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern) {
- if (pStrPattern[iPattern] == '\'') {
- wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- iPattern++;
- continue;
- } else {
- wsOutput += pStrPattern[iPattern++];
- continue;
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_FormatString::FormatNull(const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput) {
- if (wsPattern.IsEmpty()) {
- return FALSE;
- }
- CFX_WideString wsTextFormat;
- GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
- int32_t iPattern = 0;
- const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
- int32_t iLenPattern = wsTextFormat.GetLength();
- while (iPattern < iLenPattern) {
- if (pStrPattern[iPattern] == '\'') {
- wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
- iPattern++;
- continue;
- } else {
- wsOutput += pStrPattern[iPattern++];
- continue;
- }
- }
- return TRUE;
-}
-IFX_Locale* CFX_FormatString::GetPatternLocale(
- const CFX_WideStringC& wsLocale) {
- if (m_bUseLCID) {
- }
- return m_pLocaleMgr->GetLocaleByName(wsLocale);
-}
-#define FXMATH_DECIMAL_SCALELIMIT 0x1c
-#define FXMATH_DECIMAL_NEGMASK (0x80000000L)
-#define FXMATH_DECIMAL_FORCEBOOL(x) (!(!(x)))
-#define FXMATH_DECIMAL_MAKEFLAGS(NEG, SCALE) \
- (((SCALE) << 0x10) | ((NEG) ? FXMATH_DECIMAL_NEGMASK : 0))
-#define FXMATH_DECIMAL_FLAGS2NEG(FLAGS) \
- FXMATH_DECIMAL_FORCEBOOL((FLAGS)&FXMATH_DECIMAL_NEGMASK)
-#define FXMATH_DECIMAL_FLAGS2SCALE(FLAGS) \
- ((uint8_t)(((FLAGS) & ~FXMATH_DECIMAL_NEGMASK) >> 0x10))
-#define FXMATH_DECIMAL_RSHIFT32BIT(x) ((x) >> 0x10 >> 0x10)
-#define FXMATH_DECIMAL_LSHIFT32BIT(x) ((x) << 0x10 << 0x10)
-static inline uint8_t fxmath_decimal_helper_div10(uint64_t& phi,
- uint64_t& pmid,
- uint64_t& plo) {
- uint8_t retVal;
- pmid += FXMATH_DECIMAL_LSHIFT32BIT(phi % 0xA);
- phi /= 0xA;
- plo += FXMATH_DECIMAL_LSHIFT32BIT(pmid % 0xA);
- pmid /= 0xA;
- retVal = plo % 0xA;
- plo /= 0xA;
- return retVal;
-}
-static inline uint8_t fxmath_decimal_helper_div10_any(uint64_t nums[],
- uint8_t numcount) {
- uint8_t retVal = 0;
- for (int i = numcount - 1; i > 0; i--) {
- nums[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(nums[i] % 0xA);
- nums[i] /= 0xA;
- }
- if (numcount) {
- retVal = nums[0] % 0xA;
- nums[0] /= 0xA;
- }
- return retVal;
-}
-static inline void fxmath_decimal_helper_mul10(uint64_t& phi,
- uint64_t& pmid,
- uint64_t& plo) {
- plo *= 0xA;
- pmid = pmid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(plo);
- plo = (uint32_t)plo;
- phi = phi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(pmid);
- pmid = (uint32_t)pmid;
-}
-static inline void fxmath_decimal_helper_mul10_any(uint64_t nums[],
- uint8_t numcount) {
- nums[0] *= 0xA;
- for (int i = 1; i < numcount; i++) {
- nums[i] = nums[i] * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(nums[i - 1]);
- nums[i - 1] = (uint32_t)nums[i - 1];
- }
-}
-static inline void fxmath_decimal_helper_normalize(uint64_t& phi,
- uint64_t& pmid,
- uint64_t& plo) {
- phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
- pmid = (uint32_t)pmid;
- pmid += FXMATH_DECIMAL_RSHIFT32BIT(plo);
- plo = (uint32_t)plo;
- phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
- pmid = (uint32_t)pmid;
-}
-static inline void fxmath_decimal_helper_normalize_any(uint64_t nums[],
- uint8_t len) {
- {
- for (int i = len - 2; i > 0; i--) {
- nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
- nums[i] = (uint32_t)nums[i];
- }
- }
- {
- for (int i = 0; i < len - 1; i++) {
- nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
- nums[i] = (uint32_t)nums[i];
- }
- }
-}
-static inline int8_t fxmath_decimal_helper_raw_compare(uint32_t hi1,
- uint32_t mid1,
- uint32_t lo1,
- uint32_t hi2,
- uint32_t mid2,
- uint32_t lo2) {
- int8_t retVal = 0;
- if (!retVal) {
- retVal += (hi1 > hi2 ? 1 : (hi1 < hi2 ? -1 : 0));
- }
- if (!retVal) {
- retVal += (mid1 > mid2 ? 1 : (mid1 < mid2 ? -1 : 0));
- }
- if (!retVal) {
- retVal += (lo1 > lo2 ? 1 : (lo1 < lo2 ? -1 : 0));
- }
- return retVal;
-}
-static inline int8_t fxmath_decimal_helper_raw_compare_any(uint64_t a[],
- uint8_t al,
- uint64_t b[],
- uint8_t bl) {
- int8_t retVal = 0;
- for (int i = std::max(al - 1, bl - 1); i >= 0; i--) {
- uint64_t l = (i >= al ? 0 : a[i]), r = (i >= bl ? 0 : b[i]);
- retVal += (l > r ? 1 : (l < r ? -1 : 0));
- if (retVal) {
- return retVal;
- }
- }
- return retVal;
-}
-static inline void fxmath_decimal_helper_dec_any(uint64_t a[], uint8_t al) {
- for (int i = 0; i < al; i++) {
- if (a[i]--) {
- return;
- }
- }
-}
-static inline void fxmath_decimal_helper_inc_any(uint64_t a[], uint8_t al) {
- for (int i = 0; i < al; i++) {
- a[i]++;
- if ((uint32_t)a[i] == a[i]) {
- return;
- }
- a[i] = 0;
- }
-}
-static inline void fxmath_decimal_helper_raw_mul(uint64_t a[],
- uint8_t al,
- uint64_t b[],
- uint8_t bl,
- uint64_t c[],
- uint8_t cl) {
- assert(al + bl <= cl);
- {
- for (int i = 0; i < cl; i++) {
- c[i] = 0;
- }
- }
- {
- for (int i = 0; i < al; i++) {
- for (int j = 0; j < bl; j++) {
- uint64_t m = (uint64_t)a[i] * b[j];
- c[i + j] += (uint32_t)m;
- c[i + j + 1] += FXMATH_DECIMAL_RSHIFT32BIT(m);
- }
- }
- }
- {
- for (int i = 0; i < cl - 1; i++) {
- c[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(c[i]);
- c[i] = (uint32_t)c[i];
- }
- }
- {
- for (int i = 0; i < cl; i++) {
- c[i] = (uint32_t)c[i];
- }
- }
-}
-static inline void fxmath_decimal_helper_raw_div(uint64_t a[],
- uint8_t al,
- uint64_t b[],
- uint8_t bl,
- uint64_t c[],
- uint8_t cl) {
- int i;
- for (i = 0; i < cl; i++) {
- c[i] = 0;
- }
- uint64_t left[16] = {0}, right[16] = {0};
- left[0] = 0;
- for (i = 0; i < al; i++) {
- right[i] = a[i];
- }
- uint64_t tmp[16];
- while (fxmath_decimal_helper_raw_compare_any(left, al, right, al) <= 0) {
- uint64_t cur[16];
- for (i = 0; i < al; i++) {
- cur[i] = left[i] + right[i];
- }
- for (i = al - 1; i >= 0; i--) {
- if (i) {
- cur[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(cur[i] % 2);
- }
- cur[i] /= 2;
- }
- fxmath_decimal_helper_raw_mul(cur, al, b, bl, tmp, 16);
- switch (fxmath_decimal_helper_raw_compare_any(tmp, 16, a, al)) {
- case -1:
- for (i = 0; i < 16; i++) {
- left[i] = cur[i];
- }
- left[0]++;
- fxmath_decimal_helper_normalize_any(left, al);
- break;
- case 1:
- for (i = 0; i < 16; i++) {
- right[i] = cur[i];
- }
- fxmath_decimal_helper_dec_any(right, al);
- break;
- case 0:
- for (i = 0; i < std::min(al, cl); i++) {
- c[i] = cur[i];
- }
- return;
- }
- }
- for (i = 0; i < std::min(al, cl); i++) {
- c[i] = left[i];
- }
-}
-static inline FX_BOOL fxmath_decimal_helper_outofrange(uint64_t a[],
- uint8_t al,
- uint8_t goal) {
- for (int i = goal; i < al; i++) {
- if (a[i]) {
- return TRUE;
- }
- }
- return FALSE;
-}
-static inline void fxmath_decimal_helper_shrinkintorange(uint64_t a[],
- uint8_t al,
- uint8_t goal,
- uint8_t& scale) {
- FX_BOOL bRoundUp = FALSE;
- while (scale != 0 && (scale > FXMATH_DECIMAL_SCALELIMIT ||
- fxmath_decimal_helper_outofrange(a, al, goal))) {
- bRoundUp = fxmath_decimal_helper_div10_any(a, al) >= 5;
- scale--;
- }
- if (bRoundUp) {
- fxmath_decimal_helper_normalize_any(a, goal);
- fxmath_decimal_helper_inc_any(a, goal);
- }
-}
-static inline void fxmath_decimal_helper_truncate(uint64_t& phi,
- uint64_t& pmid,
- uint64_t& plo,
- uint8_t& scale,
- uint8_t minscale = 0) {
- while (scale > minscale) {
- uint64_t thi = phi, tmid = pmid, tlo = plo;
- if (fxmath_decimal_helper_div10(thi, tmid, tlo) != 0) {
- break;
- }
- phi = thi, pmid = tmid, plo = tlo;
- scale--;
- }
-}
-CFX_Decimal::CFX_Decimal() {
- m_uLo = m_uMid = m_uHi = m_uFlags = 0;
-}
-CFX_Decimal::CFX_Decimal(uint64_t val) {
- m_uLo = (uint32_t)val;
- m_uMid = (uint32_t)FXMATH_DECIMAL_RSHIFT32BIT(val);
- m_uHi = 0;
- m_uFlags = 0;
-}
-CFX_Decimal::CFX_Decimal(uint32_t val) {
- m_uLo = (uint32_t)val;
- m_uMid = m_uHi = 0;
- m_uFlags = 0;
-}
-CFX_Decimal::CFX_Decimal(uint32_t lo,
- uint32_t mid,
- uint32_t hi,
- FX_BOOL neg,
- uint8_t scale) {
- scale = (scale > FXMATH_DECIMAL_SCALELIMIT ? 0 : scale);
- m_uLo = lo;
- m_uMid = mid;
- m_uHi = hi;
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(neg && IsNotZero(), scale);
-}
-CFX_Decimal::CFX_Decimal(int32_t val) {
- if (val >= 0) {
- *this = CFX_Decimal((uint32_t)val);
- } else {
- *this = CFX_Decimal((uint32_t)-val);
- SetNegate();
- }
-}
-CFX_Decimal::CFX_Decimal(int64_t val) {
- if (val >= 0) {
- *this = CFX_Decimal((uint64_t)val);
- } else {
- *this = CFX_Decimal((uint64_t)-val);
- SetNegate();
- }
-}
-CFX_Decimal::CFX_Decimal(FX_FLOAT val, uint8_t scale) {
- FX_FLOAT newval = fabs(val);
- uint64_t phi, pmid, plo;
- plo = (uint64_t)newval;
- pmid = (uint64_t)(newval / 1e32);
- phi = (uint64_t)(newval / 1e64);
- newval = FXSYS_fmod(newval, 1.0f);
- for (uint8_t iter = 0; iter < scale; iter++) {
- fxmath_decimal_helper_mul10(phi, pmid, plo);
- newval *= 10;
- plo += (uint64_t)newval;
- newval = FXSYS_fmod(newval, 1.0f);
- }
- plo += FXSYS_round(newval);
- fxmath_decimal_helper_normalize(phi, pmid, plo);
- m_uHi = (uint32_t)phi;
- m_uMid = (uint32_t)pmid;
- m_uLo = (uint32_t)plo;
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(val < 0 && IsNotZero(), scale);
-}
-CFX_Decimal::CFX_Decimal(const CFX_WideStringC& strObj) {
- const FX_WCHAR* str = strObj.GetPtr();
- const FX_WCHAR* strBound = str + strObj.GetLength();
- FX_BOOL pointmet = 0;
- FX_BOOL negmet = 0;
- uint8_t scale = 0;
- m_uHi = m_uMid = m_uLo = 0;
- while (str != strBound && *str == ' ') {
- str++;
- }
- if (str != strBound && *str == '-') {
- negmet = 1;
- str++;
- } else if (str != strBound && *str == '+') {
- str++;
- }
- while (str != strBound && ((*str >= '0' && *str <= '9') || *str == '.') &&
- scale < FXMATH_DECIMAL_SCALELIMIT) {
- if (*str == '.') {
- if (pointmet) {
- goto cont;
- }
- pointmet = 1;
- } else {
- m_uHi = m_uHi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((uint64_t)m_uMid * 0xA);
- m_uMid = m_uMid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((uint64_t)m_uLo * 0xA);
- m_uLo = m_uLo * 0xA + (*str - '0');
- if (pointmet) {
- scale++;
- }
- }
- cont:
- str++;
- }
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(negmet && IsNotZero(), scale);
-}
-CFX_Decimal::CFX_Decimal(const CFX_ByteStringC& strObj) {
- CFX_WideString wstrObj;
- wstrObj.ConvertFrom(strObj);
- *this = CFX_Decimal(wstrObj);
-}
-CFX_Decimal::operator CFX_WideString() const {
- CFX_WideString retString;
- CFX_WideString tmpbuf;
- uint64_t phi = m_uHi, pmid = m_uMid, plo = m_uLo;
- while (phi || pmid || plo) {
- tmpbuf += fxmath_decimal_helper_div10(phi, pmid, plo) + '0';
- }
- uint8_t outputlen = (uint8_t)tmpbuf.GetLength();
- uint8_t scale = (uint8_t)FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
- while (scale >= outputlen) {
- tmpbuf += '0';
- outputlen++;
- }
- if (FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero()) {
- retString += '-';
- }
- for (uint8_t idx = 0; idx < outputlen; idx++) {
- if (idx == (outputlen - scale) && scale != 0) {
- retString += '.';
- }
- retString += tmpbuf[outputlen - 1 - idx];
- }
- return retString;
-}
-CFX_Decimal::operator double() const {
- double pow = (double)(1 << 16) * (1 << 16);
- double base =
- ((double)m_uHi) * pow * pow + ((double)m_uMid) * pow + ((double)m_uLo);
- int8_t scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
- FX_BOOL bNeg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags);
- return (bNeg ? -1 : 1) * base * ::pow(10.0, -scale);
-}
-void CFX_Decimal::SetScale(uint8_t newscale) {
- uint8_t oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
- if (newscale > oldscale) {
- uint64_t phi = m_uHi, pmid = m_uMid, plo = m_uLo;
- for (uint8_t iter = 0; iter < newscale - oldscale; iter++) {
- fxmath_decimal_helper_mul10(phi, pmid, plo);
- }
- m_uHi = (uint32_t)phi;
- m_uMid = (uint32_t)pmid;
- m_uLo = (uint32_t)plo;
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
- FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
- } else if (newscale < oldscale) {
- uint64_t phi, pmid, plo;
- phi = 0, pmid = 0, plo = 5;
- {
- for (uint8_t iter = 0; iter < oldscale - newscale - 1; iter++) {
- fxmath_decimal_helper_mul10(phi, pmid, plo);
- }
- }
- phi += m_uHi;
- pmid += m_uMid;
- plo += m_uLo;
- fxmath_decimal_helper_normalize(phi, pmid, plo);
- {
- for (uint8_t iter = 0; iter < oldscale - newscale; iter++) {
- fxmath_decimal_helper_div10(phi, pmid, plo);
- }
- }
- m_uHi = (uint32_t)phi;
- m_uMid = (uint32_t)pmid;
- m_uLo = (uint32_t)plo;
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
- FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
- }
-}
-uint8_t CFX_Decimal::GetScale() {
- uint8_t oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
- return oldscale;
-}
-void CFX_Decimal::SetAbs() {
- m_uFlags &= ~FXMATH_DECIMAL_NEGMASK;
-}
-void CFX_Decimal::SetNegate() {
- if (IsNotZero()) {
- m_uFlags ^= FXMATH_DECIMAL_NEGMASK;
- }
-}
-void CFX_Decimal::FloorOrCeil(FX_BOOL bFloor) {
- uint64_t nums[3] = {m_uLo, m_uMid, m_uHi};
- FX_BOOL bDataLoss = FALSE;
- for (int i = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); i > 0; i--) {
- bDataLoss = fxmath_decimal_helper_div10_any(nums, 3) || bDataLoss;
- }
- if (bDataLoss && (bFloor ? FXMATH_DECIMAL_FLAGS2NEG(m_uFlags)
- : !FXMATH_DECIMAL_FLAGS2NEG(m_uFlags))) {
- fxmath_decimal_helper_inc_any(nums, 3);
- }
- m_uHi = (uint32_t)nums[2];
- m_uMid = (uint32_t)nums[1];
- m_uLo = (uint32_t)nums[0];
- m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
- FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), 0);
-}
-void CFX_Decimal::SetFloor() {
- FloorOrCeil(TRUE);
-}
-void CFX_Decimal::SetCeiling() {
- FloorOrCeil(FALSE);
-}
-void CFX_Decimal::SetTruncate() {
- FloorOrCeil(!FXMATH_DECIMAL_FLAGS2NEG(m_uFlags));
-}
-void CFX_Decimal::Swap(CFX_Decimal& val) {
- uint32_t tmp;
- tmp = m_uHi;
- m_uHi = val.m_uHi;
- val.m_uHi = tmp;
- tmp = m_uMid;
- m_uMid = val.m_uMid;
- val.m_uMid = tmp;
- tmp = m_uLo;
- m_uLo = val.m_uLo;
- val.m_uLo = tmp;
- tmp = m_uFlags;
- m_uFlags = val.m_uFlags;
- val.m_uFlags = tmp;
-}
-int8_t CFX_Decimal::Compare(const CFX_Decimal& val) const {
- CFX_Decimal lhs = *this, rhs = val;
- int8_t retVal = 0;
- if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) !=
- FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
- uint8_t scale = std::min(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags),
- FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
- lhs.SetScale(scale);
- rhs.SetScale(scale);
- }
- retVal = -(FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) -
- FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
- if (retVal) {
- return retVal;
- }
- retVal = fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo,
- rhs.m_uHi, rhs.m_uMid, rhs.m_uLo);
- return (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) ? -retVal : retVal);
-}
-CFX_Decimal CFX_Decimal::AddOrMinus(const CFX_Decimal& val,
- FX_BOOL isAdding) const {
- CFX_Decimal lhs = *this, rhs = val;
- if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) !=
- FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
- uint8_t scale = std::max(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags),
- FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
- lhs.SetScale(scale);
- rhs.SetScale(scale);
- }
- if (!isAdding) {
- rhs.SetNegate();
- }
- FX_BOOL doRawAdd = (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) ==
- FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
- if (doRawAdd) {
- uint64_t phi = lhs.m_uHi, pmid = lhs.m_uMid, plo = lhs.m_uLo;
- phi += rhs.m_uHi;
- pmid += rhs.m_uMid;
- plo += rhs.m_uLo;
- fxmath_decimal_helper_normalize(phi, pmid, plo);
- if (FXMATH_DECIMAL_RSHIFT32BIT(phi) &&
- FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != 0) {
- fxmath_decimal_helper_div10(phi, pmid, plo);
- lhs.m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
- FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags),
- FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) - 1);
- }
- lhs.m_uHi = (uint32_t)phi;
- lhs.m_uMid = (uint32_t)pmid;
- lhs.m_uLo = (uint32_t)plo;
- return lhs;
- } else {
- if (fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo,
- rhs.m_uHi, rhs.m_uMid,
- rhs.m_uLo) < 0) {
- lhs.Swap(rhs);
- }
- lhs.m_uHi -= rhs.m_uHi;
- if (lhs.m_uMid < rhs.m_uMid) {
- lhs.m_uHi--;
- }
- lhs.m_uMid -= rhs.m_uMid;
- if (lhs.m_uLo < rhs.m_uLo) {
- if (!lhs.m_uMid) {
- lhs.m_uHi--;
- }
- lhs.m_uMid--;
- }
- lhs.m_uLo -= rhs.m_uLo;
- return lhs;
- }
-}
-CFX_Decimal CFX_Decimal::Multiply(const CFX_Decimal& val) const {
- uint64_t a[3] = {m_uLo, m_uMid, m_uHi},
- b[3] = {val.m_uLo, val.m_uMid, val.m_uHi};
- uint64_t c[6];
- fxmath_decimal_helper_raw_mul(a, 3, b, 3, c, 6);
- FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^
- FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
- uint8_t scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) +
- FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
- fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
- return CFX_Decimal((uint32_t)c[0], (uint32_t)c[1], (uint32_t)c[2], neg,
- scale);
-}
-CFX_Decimal CFX_Decimal::Divide(const CFX_Decimal& val) const {
- if (!val.IsNotZero()) {
- return CFX_Decimal();
- }
- FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^
- FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
- uint64_t a[7] = {m_uLo, m_uMid, m_uHi},
- b[3] = {val.m_uLo, val.m_uMid, val.m_uHi}, c[7] = {0};
- uint8_t scale = 0;
- if (FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) <
- FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags)) {
- for (int i = FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags) -
- FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
- i > 0; i--) {
- fxmath_decimal_helper_mul10_any(a, 7);
- }
- } else {
- scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) -
- FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
- }
- uint8_t minscale = scale;
- if (!IsNotZero()) {
- return CFX_Decimal(0, 0, 0, 0, minscale);
- }
- while (!a[6]) {
- fxmath_decimal_helper_mul10_any(a, 7);
- scale++;
- }
- fxmath_decimal_helper_div10_any(a, 7);
- scale--;
- fxmath_decimal_helper_raw_div(a, 6, b, 3, c, 7);
- fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
- fxmath_decimal_helper_truncate(c[2], c[1], c[0], scale, minscale);
- return CFX_Decimal((uint32_t)c[0], (uint32_t)c[1], (uint32_t)c[2], neg,
- scale);
-}
-CFX_Decimal CFX_Decimal::Modulus(const CFX_Decimal& val) const {
- CFX_Decimal lhs = *this, rhs_abs = val;
- rhs_abs.SetAbs();
- if (!rhs_abs.IsNotZero()) {
- return *this;
- }
- while (TRUE) {
- CFX_Decimal lhs_abs = lhs;
- lhs_abs.SetAbs();
- if (lhs_abs < rhs_abs) {
- break;
- }
- CFX_Decimal quot = lhs / rhs_abs;
- quot.SetTruncate();
- lhs = lhs - quot * rhs_abs;
- }
- return lhs;
-}
-FX_BOOL CFX_Decimal::operator==(const CFX_Decimal& val) const {
- return Compare(val) == 0;
-}
-FX_BOOL CFX_Decimal::operator<=(const CFX_Decimal& val) const {
- return Compare(val) <= 0;
-}
-FX_BOOL CFX_Decimal::operator>=(const CFX_Decimal& val) const {
- return Compare(val) >= 0;
-}
-FX_BOOL CFX_Decimal::operator!=(const CFX_Decimal& val) const {
- return Compare(val) != 0;
-}
-FX_BOOL CFX_Decimal::operator<(const CFX_Decimal& val) const {
- return Compare(val) < 0;
-}
-FX_BOOL CFX_Decimal::operator>(const CFX_Decimal& val) const {
- return Compare(val) > 0;
-}
-CFX_Decimal CFX_Decimal::operator+(const CFX_Decimal& val) const {
- return AddOrMinus(val, TRUE);
-}
-CFX_Decimal CFX_Decimal::operator-(const CFX_Decimal& val) const {
- return AddOrMinus(val, FALSE);
-}
-CFX_Decimal CFX_Decimal::operator*(const CFX_Decimal& val) const {
- return Multiply(val);
-}
-CFX_Decimal CFX_Decimal::operator/(const CFX_Decimal& val) const {
- return Divide(val);
-}
-CFX_Decimal CFX_Decimal::operator%(const CFX_Decimal& val) const {
- return Modulus(val);
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "core/include/fxcrt/fx_xml.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_localeimp.h"
+
+#define FX_LOCALECATEGORY_DateHash 0xbde9abde
+#define FX_LOCALECATEGORY_TimeHash 0x2d71b00f
+#define FX_LOCALECATEGORY_DateTimeHash 0x158c72ed
+#define FX_LOCALECATEGORY_NumHash 0x0b4ff870
+#define FX_LOCALECATEGORY_TextHash 0x2d08af85
+#define FX_LOCALECATEGORY_ZeroHash 0x568cb500
+#define FX_LOCALECATEGORY_NullHash 0x052931bb
+typedef struct _FX_LOCALESUBCATEGORYINFO {
+ uint32_t uHash;
+ const FX_WCHAR* pName;
+ int32_t eSubCategory;
+} FX_LOCALESUBCATEGORYINFO, *FX_LPLOCALESUBCATEGORYINFO;
+typedef FX_LOCALESUBCATEGORYINFO const* FX_LPCLOCALESUBCATEGORYINFO;
+const static FX_LOCALESUBCATEGORYINFO g_FXLocaleDateTimeSubCatData[] = {
+ {0x14da2125, L"default", FX_LOCALEDATETIMESUBCATEGORY_Default},
+ {0x9041d4b0, L"short", FX_LOCALEDATETIMESUBCATEGORY_Short},
+ {0xa084a381, L"medium", FX_LOCALEDATETIMESUBCATEGORY_Medium},
+ {0xcdce56b3, L"full", FX_LOCALEDATETIMESUBCATEGORY_Full},
+ {0xf6b4afb0, L"long", FX_LOCALEDATETIMESUBCATEGORY_Long},
+};
+const static int32_t g_iFXLocaleDateTimeSubCatCount =
+ sizeof(g_FXLocaleDateTimeSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
+const static FX_LOCALESUBCATEGORYINFO g_FXLocaleNumSubCatData[] = {
+ {0x46f95531, L"percent", FX_LOCALENUMPATTERN_Percent},
+ {0x4c4e8acb, L"currency", FX_LOCALENUMPATTERN_Currency},
+ {0x54034c2f, L"decimal", FX_LOCALENUMPATTERN_Decimal},
+ {0x7568e6ae, L"integer", FX_LOCALENUMPATTERN_Integer},
+};
+const static int32_t g_iFXLocaleNumSubCatCount =
+ sizeof(g_FXLocaleNumSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
+typedef struct _FX_LOCALETIMEZONEINFO {
+ FX_DWORD uHash;
+ int16_t iHour;
+ int16_t iMinute;
+} FX_LOCALETIMEZONEINFO, *FX_LPLOCALETIMEZONEINFO;
+typedef FX_LOCALETIMEZONEINFO const* FX_LPCLOCALETIMEZONEINFO;
+const static FX_LOCALETIMEZONEINFO g_FXLocaleTimeZoneData[] = {
+ {FXBSTR_ID(0, 'C', 'D', 'T'), -5, 0}, {FXBSTR_ID(0, 'C', 'S', 'T'), -6, 0},
+ {FXBSTR_ID(0, 'E', 'D', 'T'), -4, 0}, {FXBSTR_ID(0, 'E', 'S', 'T'), -5, 0},
+ {FXBSTR_ID(0, 'M', 'D', 'T'), -6, 0}, {FXBSTR_ID(0, 'M', 'S', 'T'), -7, 0},
+ {FXBSTR_ID(0, 'P', 'D', 'T'), -7, 0}, {FXBSTR_ID(0, 'P', 'S', 'T'), -8, 0},
+};
+const static int32_t g_iFXLocaleTimeZoneCount =
+ sizeof(g_FXLocaleTimeZoneData) / sizeof(FX_LOCALETIMEZONEINFO);
+const static CFX_WideStringC gs_wsTextSymbols = FX_WSTRC(L"AXO09");
+const static CFX_WideStringC gs_wsTimeSymbols = FX_WSTRC(L"hHkKMSFAzZ");
+const static CFX_WideStringC gs_wsDateSymbols = FX_WSTRC(L"DJMEeGgYwW");
+const static CFX_WideStringC gs_wsConstChars = FX_WSTRC(L",-:/. ");
+static FX_STRSIZE FX_Local_Find(const CFX_WideStringC& wsSymbols,
+ FX_WCHAR ch,
+ FX_STRSIZE nStart = 0) {
+ FX_STRSIZE nLength = wsSymbols.GetLength();
+ if (nLength < 1 || nStart > nLength) {
+ return -1;
+ }
+ const FX_WCHAR* lpsz =
+ (const FX_WCHAR*)FXSYS_wcschr(wsSymbols.GetPtr() + nStart, ch);
+ return (lpsz == NULL) ? -1 : (FX_STRSIZE)(lpsz - wsSymbols.GetPtr());
+}
+static const FX_WCHAR* const gs_LocalNumberSymbols[] = {
+ L"decimal", L"grouping", L"percent", L"minus",
+ L"zero", L"currencySymbol", L"currencyName",
+};
+IFX_Locale* IFX_Locale::Create(CXML_Element* pLocaleData) {
+ return new CFX_Locale(pLocaleData);
+}
+CFX_Locale::CFX_Locale(CXML_Element* pLocaleData) {
+ m_pElement = pLocaleData;
+}
+CFX_Locale::~CFX_Locale() {}
+CFX_WideString CFX_Locale::GetName() {
+ return CFX_WideString();
+}
+static CFX_WideString FX_GetXMLContent(const CFX_ByteStringC& bsSpace,
+ CXML_Element* pxmlElement,
+ const CFX_ByteStringC& bsTag,
+ const CFX_WideStringC& wsName) {
+ CXML_Element* pDatePattern = NULL;
+ int32_t nCount = pxmlElement->CountElements(bsSpace, bsTag);
+ int32_t i = 0;
+ for (; i < nCount; i++) {
+ pDatePattern = pxmlElement->GetElement(bsSpace, bsTag, i);
+ if (pDatePattern->GetAttrValue("name") == wsName) {
+ break;
+ }
+ }
+ if (i < nCount && pDatePattern) {
+ return pDatePattern->GetContent(0);
+ }
+ return L"";
+}
+void CFX_Locale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+ CFX_WideString& wsNumSymbol) const {
+ if (!m_pElement) {
+ return;
+ }
+ CFX_ByteString bsSpace;
+ CFX_WideString wsName = gs_LocalNumberSymbols[eType];
+ CXML_Element* pNumberSymbols =
+ m_pElement->GetElement(bsSpace, "numberSymbols");
+ if (!pNumberSymbols) {
+ return;
+ }
+ wsNumSymbol =
+ FX_GetXMLContent(bsSpace, pNumberSymbols, "numberSymbol", wsName);
+}
+void CFX_Locale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const {
+ if (!m_pElement) {
+ return;
+ }
+ CFX_ByteString bsSpace;
+ CXML_Element* pNumberSymbols =
+ m_pElement->GetElement(bsSpace, "dateTimeSymbols");
+ if (!pNumberSymbols) {
+ return;
+ }
+ wsDtSymbol = pNumberSymbols->GetContent(0);
+}
+static void FX_GetCalendarSymbol(CXML_Element* pXmlElement,
+ const CFX_ByteString& symbol_type,
+ int32_t index,
+ FX_BOOL bAbbr,
+ CFX_WideString& wsName) {
+ CFX_ByteString bsSpace;
+ CFX_ByteString pstrSymbolNames = symbol_type + "Names";
+ CXML_Element* pChild = pXmlElement->GetElement(bsSpace, "calendarSymbols");
+ if (!pChild) {
+ return;
+ }
+ CXML_Element* pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames);
+ if (!pSymbolNames) {
+ return;
+ }
+ if (pSymbolNames->GetAttrInteger("abbr") != bAbbr) {
+ pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames, 1);
+ }
+ if (pSymbolNames && pSymbolNames->GetAttrInteger("abbr") == bAbbr) {
+ CXML_Element* pSymbolName =
+ pSymbolNames->GetElement(bsSpace, symbol_type, index);
+ if (pSymbolName) {
+ wsName = pSymbolName->GetContent(0);
+ }
+ }
+}
+void CFX_Locale::GetMonthName(int32_t nMonth,
+ CFX_WideString& wsMonthName,
+ FX_BOOL bAbbr) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "month", nMonth, bAbbr, wsMonthName);
+}
+void CFX_Locale::GetDayName(int32_t nWeek,
+ CFX_WideString& wsDayName,
+ FX_BOOL bAbbr) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "day", nWeek, bAbbr, wsDayName);
+}
+void CFX_Locale::GetMeridiemName(CFX_WideString& wsMeridiemName,
+ FX_BOOL bAM) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "meridiem", bAM ? 0 : 1, FALSE,
+ wsMeridiemName);
+}
+static int32_t FX_ParseTimeZone(const FX_WCHAR* pStr,
+ int32_t iLen,
+ FX_TIMEZONE& tz) {
+ tz.tzHour = 0;
+ tz.tzMinute = 0;
+ if (iLen < 0) {
+ return 0;
+ }
+ int32_t iStart = 1;
+ int32_t iEnd = iStart + 2;
+ while (iStart < iLen && iStart < iEnd) {
+ tz.tzHour = tz.tzHour * 10 + pStr[iStart++] - '0';
+ }
+ if (iStart < iLen && pStr[iStart] == ':') {
+ iStart++;
+ }
+ iEnd = iStart + 2;
+ while (iStart < iLen && iStart < iEnd) {
+ tz.tzMinute = tz.tzMinute * 10 + pStr[iStart++] - '0';
+ }
+ if (pStr[0] == '-') {
+ tz.tzHour = -tz.tzHour;
+ }
+ return iStart;
+}
+void CFX_Locale::GetTimeZone(FX_TIMEZONE& tz) const {
+ tz.tzHour = 0;
+ tz.tzMinute = 0;
+ if (!m_pElement) {
+ return;
+ }
+ CXML_Element* pxmlTimeZone = m_pElement->GetElement("", "timeZone");
+ if (pxmlTimeZone) {
+ CFX_WideString wsTimeZone = pxmlTimeZone->GetContent(0);
+ FX_ParseTimeZone(wsTimeZone, wsTimeZone.GetLength(), tz);
+ }
+}
+void CFX_Locale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "era", bAD ? 0 : 1, FALSE, wsEraName);
+}
+static void FX_GetPattern(CXML_Element* pXmlElement,
+ const CFX_ByteString& bsCategory,
+ const CFX_WideString& wsSubCategory,
+ CFX_WideString& wsPattern) {
+ CFX_ByteString bsSpace;
+ CXML_Element* pDatePatterns =
+ pXmlElement->GetElement(bsSpace, bsCategory + "s");
+ if (!pDatePatterns) {
+ return;
+ }
+ wsPattern =
+ FX_GetXMLContent(bsSpace, pDatePatterns, bsCategory, wsSubCategory);
+}
+static void FX_GetDateTimePattern(CXML_Element* pXmlElement,
+ const CFX_ByteString& bsCategory,
+ FX_LOCALEDATETIMESUBCATEGORY eType,
+ CFX_WideString& wsPattern) {
+ CFX_WideString wsType = g_FXLocaleDateTimeSubCatData[eType].pName;
+ FX_GetPattern(pXmlElement, bsCategory, wsType, wsPattern);
+}
+void CFX_Locale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+ CFX_WideString& wsPattern) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetDateTimePattern(m_pElement, "datePattern", eType, wsPattern);
+}
+void CFX_Locale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+ CFX_WideString& wsPattern) const {
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetDateTimePattern(m_pElement, "timePattern", eType, wsPattern);
+}
+void CFX_Locale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+ CFX_WideString& wsPattern) const {
+ CFX_WideString wsType = g_FXLocaleNumSubCatData[eType].pName;
+ FX_GetPattern(m_pElement, "numberPattern", wsType, wsPattern);
+}
+static FX_BOOL FX_IsDigit(FX_WCHAR c) {
+ return c >= '0' && c <= '9';
+}
+static FX_BOOL FX_IsAlpha(FX_WCHAR c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+static FX_BOOL FX_IsSpace(FX_WCHAR c) {
+ return (c == 0x20) || (c == 0x0d) || (c == 0x0a) || (c == 0x09);
+}
+static const FX_FLOAT gs_fraction_scales[] = {
+ 0.1f, 0.01f, 0.001f, 0.0001f,
+ 0.00001f, 0.000001f, 0.0000001f, 0.00000001f,
+ 0.000000001f, 0.0000000001f, 0.00000000001f};
+static const int32_t gs_fraction_count =
+ sizeof(gs_fraction_scales) / sizeof(FX_FLOAT);
+class CFX_LCNumeric {
+ public:
+ CFX_LCNumeric();
+ CFX_LCNumeric(int64_t integral,
+ FX_DWORD fractional = 0,
+ int32_t exponent = 0);
+ CFX_LCNumeric(FX_FLOAT dbRetValue);
+ CFX_LCNumeric(double dbvalue);
+ CFX_LCNumeric(CFX_WideString& wsNumeric);
+
+ FX_FLOAT GetFloat() const;
+ double GetDouble() const;
+ CFX_WideString ToString() const;
+ CFX_WideString ToString(int32_t nTreading, FX_BOOL bTrimTailZeros) const;
+ int64_t m_Integral;
+ FX_DWORD m_Fractional;
+#ifdef FX_NUM_DOUBLE
+ CFX_WideString m_wsValue;
+#endif
+ int32_t m_Exponent;
+};
+static FX_BOOL FX_WStringToNumeric(const CFX_WideString& wsValue,
+ CFX_LCNumeric& lcnum) {
+ int64_t* pIntegral = &lcnum.m_Integral;
+ FX_DWORD* pFractional = &lcnum.m_Fractional;
+ int32_t* pExponent = &lcnum.m_Exponent;
+ *pIntegral = 0;
+ *pFractional = 0;
+ *pExponent = 0;
+#ifdef FX_NUM_DOUBLE
+ lcnum.m_wsValue.Empty();
+#endif
+ if (wsValue.IsEmpty()) {
+ return FALSE;
+ }
+ const int32_t nIntegralMaxLen = 17;
+ int32_t cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsValue;
+ int32_t len = wsValue.GetLength();
+ while (cc < len && FX_IsSpace(str[cc])) {
+ cc++;
+ }
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ int32_t nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.') {
+ break;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ if (nIntegralLen < nIntegralMaxLen) {
+ *pIntegral = *pIntegral * 10 + str[cc] - '0';
+ nIntegralLen++;
+ }
+ cc++;
+ }
+ *pIntegral = bNegative ? -*pIntegral : *pIntegral;
+ if (cc < len && str[cc] == '.') {
+ int scale = 0;
+ double fraction = 0.0;
+ cc++;
+ while (cc < len) {
+ if (scale >= gs_fraction_count) {
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ cc++;
+ }
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ fraction += gs_fraction_scales[scale] * (str[cc] - '0');
+ scale++;
+ cc++;
+ }
+ *pFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+ cc++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ *pExponent = *pExponent * 10 + str[cc] - '0';
+ cc++;
+ }
+ *pExponent = bExpSign ? -*pExponent : *pExponent;
+ }
+#ifdef FX_NUM_DOUBLE
+ else {
+ lcnum.m_wsValue = wsValue;
+ }
+#endif
+ return TRUE;
+}
+CFX_LCNumeric::CFX_LCNumeric() {
+ m_Integral = 0;
+ m_Fractional = 0;
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(int64_t integral,
+ FX_DWORD fractional,
+ int32_t exponent) {
+ m_Integral = integral;
+ m_Fractional = fractional;
+ m_Exponent = exponent;
+}
+CFX_LCNumeric::CFX_LCNumeric(FX_FLOAT dbRetValue) {
+ m_Integral = (int64_t)dbRetValue;
+ m_Fractional = (FX_DWORD)(((dbRetValue > 0) ? (dbRetValue - m_Integral)
+ : (m_Integral - dbRetValue)) *
+ 4294967296);
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(double dbvalue) {
+ m_Integral = (int64_t)dbvalue;
+ m_Fractional = (FX_DWORD)(
+ ((dbvalue > 0) ? (dbvalue - m_Integral) : (m_Integral - dbvalue)) *
+ 4294967296);
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(CFX_WideString& wsNumeric) {
+ FX_WStringToNumeric(wsNumeric, *this);
+}
+FX_FLOAT CFX_LCNumeric::GetFloat() const {
+ FX_FLOAT dbRetValue = m_Fractional / 4294967296.0f;
+ dbRetValue = m_Integral + (m_Integral >= 0 ? dbRetValue : -dbRetValue);
+ if (m_Exponent != 0) {
+ dbRetValue *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
+ }
+ return dbRetValue;
+}
+double CFX_LCNumeric::GetDouble() const {
+ double value = m_Fractional / 4294967296.0;
+ value = m_Integral + (m_Integral >= 0 ? value : -value);
+ if (m_Exponent != 0) {
+ value *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
+ }
+ return value;
+}
+CFX_WideString CFX_LCNumeric::ToString() const {
+ return ToString(8, TRUE);
+}
+CFX_WideString CFX_LCNumeric::ToString(int32_t nTreading,
+ FX_BOOL bTrimTailZeros) const {
+#ifdef FX_NUM_DOUBLE
+ CFX_WideString wsResult;
+ if (!m_wsValue.IsEmpty()) {
+ const int32_t nIntegralMaxLen = 17;
+ int32_t cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
+ int32_t len = m_wsValue.GetLength();
+ while (cc < len && FX_IsSpace(str[cc])) {
+ cc++;
+ }
+ if (cc >= len) {
+ return wsResult;
+ }
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ int32_t nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.') {
+ break;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return wsResult;
+ }
+ }
+ if (nIntegralLen < nIntegralMaxLen) {
+ *pIntegral = *pIntegral * 10 + str[cc] - '0';
+ nIntegralLen++;
+ }
+ cc++;
+ }
+ *pIntegral = bNegative ? -*pIntegral : *pIntegral;
+ if (cc < len && str[cc] == '.') {
+ int scale = 0;
+ double fraction = 0.0;
+ cc++;
+ while (cc < len) {
+ if (scale >= gs_fraction_count) {
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ cc++;
+ }
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ fraction += gs_fraction_scales[scale] * (str[cc] - '0');
+ scale++;
+ cc++;
+ }
+ *pFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ }
+ double dbValeu = GetDouble();
+ int64_t iInte = (int64_t)dbValeu;
+ wsResult.Format(L"%l", (int64_t)iInte);
+ if (m_Fractional) {
+ CFX_WideString wsFormat;
+ wsFormat.Format(L"%%.%dG", nTreading);
+ double dblMantissa = (dbValeu > 0) ? (dbValeu - iInte) : (iInte - dbValeu);
+ CFX_WideString wsFrac;
+ wsFrac.Format((const FX_WCHAR*)wsFormat, dblMantissa);
+ wsResult +=
+ CFX_WideStringC((const FX_WCHAR*)wsFrac + 1, wsFrac.GetLength() - 1);
+ if (bTrimTailZeros && nTreading > 0) {
+ wsResult.TrimRight(L"0");
+ wsResult.TrimRight(L".");
+ }
+ }
+#endif
+ CFX_WideString wsFormat;
+ wsFormat.Format(L"%%.%df", nTreading);
+ CFX_WideString wsResult;
+ wsResult.Format(wsFormat.c_str(), GetDouble());
+ if (bTrimTailZeros && nTreading > 0) {
+ wsResult.TrimRight(L"0");
+ wsResult.TrimRight(L".");
+ }
+ return wsResult;
+}
+IFX_FormatString* IFX_FormatString::Create(IFX_LocaleMgr* pLocaleMgr,
+ FX_BOOL bUseLCID) {
+ if (!pLocaleMgr) {
+ return NULL;
+ }
+ return new CFX_FormatString(pLocaleMgr, bUseLCID);
+}
+CFX_FormatString::CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID)
+ : m_pLocaleMgr(pLocaleMgr), m_bUseLCID(bUseLCID) {}
+CFX_FormatString::~CFX_FormatString() {}
+void CFX_FormatString::SplitFormatString(const CFX_WideString& wsFormatString,
+ CFX_WideStringArray& wsPatterns) {
+ int32_t iStrLen = wsFormatString.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsFormatString;
+ const FX_WCHAR* pToken = pStr;
+ const FX_WCHAR* pEnd = pStr + iStrLen;
+ FX_BOOL iQuote = FALSE;
+ while (TRUE) {
+ if (pStr >= pEnd) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ wsPatterns.Add(sub);
+ return;
+ } else if (*pStr == '\'') {
+ iQuote = !iQuote;
+ } else if (*pStr == L'|' && !iQuote) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ wsPatterns.Add(sub);
+ pToken = pStr + 1;
+ }
+ pStr++;
+ }
+}
+static CFX_WideString FX_GetLiteralText(const FX_WCHAR* pStrPattern,
+ int32_t& iPattern,
+ int32_t iLenPattern) {
+ CFX_WideString wsOutput;
+ if (pStrPattern[iPattern] != '\'') {
+ return wsOutput;
+ }
+ iPattern++;
+ int32_t iQuote = 1;
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ iQuote++;
+ if ((iPattern + 1 >= iLenPattern) ||
+ ((pStrPattern[iPattern + 1] != '\'') && (iQuote % 2 == 0))) {
+ break;
+ } else {
+ iQuote++;
+ }
+ iPattern++;
+ } else if (pStrPattern[iPattern] == '\\' && (iPattern + 1 < iLenPattern) &&
+ pStrPattern[iPattern + 1] == 'u') {
+ int32_t iKeyValue = 0;
+ iPattern += 2;
+ int32_t i = 0;
+ while (iPattern < iLenPattern && i++ < 4) {
+ FX_WCHAR ch = pStrPattern[iPattern++];
+ if ((ch >= '0' && ch <= '9')) {
+ iKeyValue = iKeyValue * 16 + ch - '0';
+ } else if ((ch >= 'a' && ch <= 'f')) {
+ iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
+ } else if ((ch >= 'A' && ch <= 'F')) {
+ iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
+ }
+ }
+ if (iKeyValue != 0) {
+ wsOutput += (FX_WCHAR)(iKeyValue & 0x0000FFFF);
+ }
+ continue;
+ }
+ wsOutput += pStrPattern[iPattern++];
+ }
+ return wsOutput;
+}
+static CFX_WideString FX_GetLiteralTextReverse(const FX_WCHAR* pStrPattern,
+ int32_t& iPattern) {
+ CFX_WideString wsOutput;
+ if (pStrPattern[iPattern] != '\'') {
+ return wsOutput;
+ }
+ iPattern--;
+ int32_t iQuote = 1;
+ while (iPattern >= 0) {
+ if (pStrPattern[iPattern] == '\'') {
+ iQuote++;
+ if (iPattern - 1 >= 0 ||
+ ((pStrPattern[iPattern - 1] != '\'') && (iQuote % 2 == 0))) {
+ break;
+ } else {
+ iQuote++;
+ }
+ iPattern--;
+ } else if (pStrPattern[iPattern] == '\\' &&
+ pStrPattern[iPattern + 1] == 'u') {
+ iPattern--;
+ int32_t iKeyValue = 0;
+ int32_t iLen = wsOutput.GetLength();
+ int32_t i = 1;
+ for (; i < iLen && i < 5; i++) {
+ FX_WCHAR ch = wsOutput[i];
+ if ((ch >= '0' && ch <= '9')) {
+ iKeyValue = iKeyValue * 16 + ch - '0';
+ } else if ((ch >= 'a' && ch <= 'f')) {
+ iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
+ } else if ((ch >= 'A' && ch <= 'F')) {
+ iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
+ }
+ }
+ if (iKeyValue != 0) {
+ wsOutput.Delete(0, i);
+ wsOutput = (FX_WCHAR)(iKeyValue & 0x0000FFFF) + wsOutput;
+ }
+ continue;
+ }
+ wsOutput = pStrPattern[iPattern--] + wsOutput;
+ }
+ return wsOutput;
+}
+FX_LOCALECATEGORY CFX_FormatString::GetCategory(
+ const CFX_WideString& wsPattern) {
+ FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
+ int32_t ccf = 0;
+ int32_t iLenf = wsPattern.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
+ FX_BOOL bBraceOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (!bBraceOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (TRUE) {
+ if (ccf == iLenf) {
+ return eCategory;
+ }
+ if (pStr[ccf] == '.' || pStr[ccf] == '(') {
+ break;
+ }
+ if (pStr[ccf] == '{') {
+ bBraceOpen = TRUE;
+ break;
+ }
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ FX_DWORD dwHash =
+ FX_HashCode_String_GetW(wsCategory, wsCategory.GetLength());
+ if (dwHash == FX_LOCALECATEGORY_DateHash) {
+ if (eCategory == FX_LOCALECATEGORY_Time) {
+ return FX_LOCALECATEGORY_DateTime;
+ }
+ eCategory = FX_LOCALECATEGORY_Date;
+ } else if (dwHash == FX_LOCALECATEGORY_TimeHash) {
+ if (eCategory == FX_LOCALECATEGORY_Date) {
+ return FX_LOCALECATEGORY_DateTime;
+ }
+ eCategory = FX_LOCALECATEGORY_Time;
+ } else if (dwHash == FX_LOCALECATEGORY_DateTimeHash) {
+ return FX_LOCALECATEGORY_DateTime;
+ } else if (dwHash == FX_LOCALECATEGORY_TextHash) {
+ return FX_LOCALECATEGORY_Text;
+ } else if (dwHash == FX_LOCALECATEGORY_NumHash) {
+ return FX_LOCALECATEGORY_Num;
+ } else if (dwHash == FX_LOCALECATEGORY_ZeroHash) {
+ return FX_LOCALECATEGORY_Zero;
+ } else if (dwHash == FX_LOCALECATEGORY_NullHash) {
+ return FX_LOCALECATEGORY_Null;
+ }
+ } else if (pStr[ccf] == '}') {
+ bBraceOpen = FALSE;
+ }
+ ccf++;
+ }
+ return eCategory;
+}
+static FX_WORD FX_WStringToLCID(const FX_WCHAR* pstrLCID) {
+ if (!pstrLCID) {
+ return 0;
+ }
+ wchar_t* pEnd;
+ return (FX_WORD)wcstol((wchar_t*)pstrLCID, &pEnd, 16);
+}
+FX_WORD CFX_FormatString::GetLCID(const CFX_WideString& wsPattern) {
+ return FX_WStringToLCID(GetLocaleName(wsPattern));
+}
+CFX_WideString CFX_FormatString::GetLocaleName(
+ const CFX_WideString& wsPattern) {
+ int32_t ccf = 0;
+ int32_t iLenf = wsPattern.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ return wsLCID;
+ }
+ ccf++;
+ }
+ return CFX_WideString();
+}
+IFX_Locale* CFX_FormatString::GetTextFormat(const CFX_WideString& wsPattern,
+ const CFX_WideStringC& wsCategory,
+ CFX_WideString& wsPurgePattern) {
+ IFX_Locale* pLocale = NULL;
+ int32_t ccf = 0;
+ int32_t iLenf = wsPattern.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
+ FX_BOOL bBrackOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ int32_t iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsSearchCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
+ pStr[ccf] != '(') {
+ wsSearchCategory += pStr[ccf];
+ ccf++;
+ }
+ if (wsSearchCategory != wsCategory) {
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBrackOpen = TRUE;
+ break;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] != '}') {
+ wsPurgePattern += pStr[ccf];
+ }
+ ccf++;
+ }
+ if (!bBrackOpen) {
+ wsPurgePattern = wsPattern;
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return pLocale;
+}
+#define FX_NUMSTYLE_Percent 0x01
+#define FX_NUMSTYLE_Exponent 0x02
+#define FX_NUMSTYLE_DotVorv 0x04
+IFX_Locale* CFX_FormatString::GetNumericFormat(const CFX_WideString& wsPattern,
+ int32_t& iDotIndex,
+ FX_DWORD& dwStyle,
+ CFX_WideString& wsPurgePattern) {
+ dwStyle = 0;
+ IFX_Locale* pLocale = NULL;
+ int32_t ccf = 0;
+ int32_t iLenf = wsPattern.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
+ FX_BOOL bFindDot = FALSE;
+ FX_BOOL bBrackOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ int32_t iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
+ pStr[ccf] != '(') {
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ if (wsCategory != FX_WSTRC(L"num")) {
+ bBrackOpen = TRUE;
+ ccf = 0;
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBrackOpen = TRUE;
+ break;
+ } else if (pStr[ccf] == '.') {
+ CFX_WideString wsSubCategory;
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
+ wsSubCategory += pStr[ccf++];
+ }
+ FX_DWORD dwSubHash =
+ FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
+ FX_LOCALENUMSUBCATEGORY eSubCategory = FX_LOCALENUMPATTERN_Decimal;
+ for (int32_t i = 0; i < g_iFXLocaleNumSubCatCount; i++) {
+ if (g_FXLocaleNumSubCatData[i].uHash == dwSubHash) {
+ eSubCategory = (FX_LOCALENUMSUBCATEGORY)g_FXLocaleNumSubCatData[i]
+ .eSubCategory;
+ break;
+ }
+ }
+ wsSubCategory.Empty();
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ FXSYS_assert(pLocale != NULL);
+ pLocale->GetNumPattern(eSubCategory, wsSubCategory);
+ iDotIndex = wsSubCategory.Find('.');
+ if (iDotIndex > 0) {
+ iDotIndex += wsPurgePattern.GetLength();
+ bFindDot = TRUE;
+ dwStyle |= FX_NUMSTYLE_DotVorv;
+ }
+ wsPurgePattern += wsSubCategory;
+ if (eSubCategory == FX_LOCALENUMPATTERN_Percent) {
+ dwStyle |= FX_NUMSTYLE_Percent;
+ }
+ continue;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] == 'E') {
+ dwStyle |= FX_NUMSTYLE_Exponent;
+ wsPurgePattern += pStr[ccf];
+ } else if (pStr[ccf] == '%') {
+ dwStyle |= FX_NUMSTYLE_Percent;
+ wsPurgePattern += pStr[ccf];
+ } else if (pStr[ccf] != '}') {
+ wsPurgePattern += pStr[ccf];
+ }
+ if (!bFindDot) {
+ if (pStr[ccf] == '.' || pStr[ccf] == 'V' || pStr[ccf] == 'v') {
+ bFindDot = TRUE;
+ iDotIndex = wsPurgePattern.GetLength() - 1;
+ dwStyle |= FX_NUMSTYLE_DotVorv;
+ }
+ }
+ ccf++;
+ }
+ if (!bFindDot) {
+ iDotIndex = wsPurgePattern.GetLength();
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return pLocale;
+}
+static FX_BOOL FX_GetNumericDotIndex(const CFX_WideString& wsNum,
+ const CFX_WideString& wsDotSymbol,
+ int32_t& iDotIndex) {
+ int32_t ccf = 0;
+ int32_t iLenf = wsNum.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsNum;
+ int32_t iLenDot = wsDotSymbol.GetLength();
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (ccf + iLenDot <= iLenf &&
+ !FXSYS_wcsncmp(pStr + ccf, (const FX_WCHAR*)wsDotSymbol,
+ iLenDot)) {
+ iDotIndex = ccf;
+ return TRUE;
+ }
+ ccf++;
+ }
+ iDotIndex = wsNum.Find('.');
+ if (iDotIndex < 0) {
+ iDotIndex = iLenf;
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::ParseText(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsValue) {
+ wsValue.Empty();
+ if (wsSrcText.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
+ if (wsTextFormat.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t iText = 0, iPattern = 0;
+ const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
+ int32_t iLenText = wsSrcText.GetLength();
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ switch (pStrPattern[iPattern]) {
+ case '\'': {
+ CFX_WideString wsLiteral =
+ FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText ||
+ FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ wsValue = wsSrcText;
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ break;
+ }
+ case 'A':
+ if (FX_IsAlpha(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ case 'X':
+ wsValue += pStrText[iText];
+ iText++;
+ iPattern++;
+ break;
+ case 'O':
+ case '0':
+ if (FX_IsDigit(pStrText[iText]) || FX_IsAlpha(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ case '9':
+ if (FX_IsDigit(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ default:
+ if (pStrPattern[iPattern] != pStrText[iText]) {
+ wsValue = wsSrcText;
+ return FALSE;
+ }
+ iPattern++;
+ iText++;
+ break;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ FX_FLOAT& fValue) {
+ fValue = 0.0f;
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t dot_index_f = -1;
+ FX_DWORD dwFormatStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale =
+ GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t iExponent = 0;
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ int32_t iGroupLen = wsGroupSymbol.GetLength();
+ CFX_WideString wsMinus;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
+ int32_t iMinusLen = wsMinus.GetLength();
+ int cc = 0, ccf = 0;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ double dbRetValue = 0;
+ double coeff = 1;
+ FX_BOOL bHavePercentSymbol = FALSE;
+ FX_BOOL bNeg = FALSE;
+ FX_BOOL bReverseParse = FALSE;
+ int32_t dot_index = 0;
+ if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) &&
+ (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ bReverseParse = TRUE;
+ }
+ bReverseParse = FALSE;
+ if (bReverseParse) {
+ ccf = lenf - 1;
+ cc = len - 1;
+ while (ccf > dot_index_f && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ }
+ cc--;
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 &&
+ !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
+ (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc--;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ } break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
+ wsSymbol);
+ int32_t iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ } break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ int32_t iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ } break;
+ case '8':
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
+ coeff *= 0.1;
+ cc++;
+ }
+ break;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 &&
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
+ iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ } break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ dot_index = cc + 1;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ coeff = 1;
+ while (ccf >= 0 && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ }
+ } else {
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 &&
+ !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
+ (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc--;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ } break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ int32_t iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ } break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ int32_t iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ } break;
+ case '8':
+ return FALSE;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 &&
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
+ iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ } break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ return FALSE;
+ }
+ if (!bReverseParse) {
+ ccf = dot_index_f + 1;
+ cc = (dot_index == len) ? len : dot_index + 1;
+ coeff = 0.1;
+ while (cc < len && ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ }
+ cc++;
+ ccf++;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ cc++;
+ }
+ } else {
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 'E': {
+ if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ cc++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ iExponent = iExponent * 10 + str[cc] - '0';
+ cc++;
+ }
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf++;
+ } break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
+ wsSymbol);
+ int32_t iSymbolLen = wsSymbol.GetLength();
+ if (cc + iSymbolLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc += iSymbolLen;
+ ccf++;
+ } break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ int32_t iSysmbolLen = wsSymbol.GetLength();
+ if (cc + iSysmbolLen <= len &&
+ !FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol,
+ iSysmbolLen)) {
+ cc += iSysmbolLen;
+ }
+ ccf++;
+ bHavePercentSymbol = TRUE;
+ } break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
+ coeff *= 0.1;
+ cc++;
+ }
+ } break;
+ case ',': {
+ if (cc + iGroupLen <= len &&
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
+ iGroupLen) == 0) {
+ cc += iGroupLen;
+ }
+ ccf++;
+ } break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ }
+ }
+ if (cc != len) {
+ return FALSE;
+ }
+ }
+ if (iExponent) {
+ dbRetValue *= FXSYS_pow(10, (FX_FLOAT)iExponent);
+ }
+ if (bHavePercentSymbol) {
+ dbRetValue /= 100.0;
+ }
+ if (bNeg) {
+ dbRetValue = -dbRetValue;
+ }
+ fValue = (FX_FLOAT)dbRetValue;
+ return TRUE;
+}
+void FX_ParseNumString(const CFX_WideString& wsNum, CFX_WideString& wsResult) {
+ int32_t iCount = wsNum.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsNum;
+ FX_WCHAR* pDst = wsResult.GetBuffer(iCount);
+ int32_t nIndex = 0;
+ FX_BOOL bMinus = FALSE;
+ int32_t i = 0;
+ for (i = 0; i < iCount; i++) {
+ FX_WCHAR wc = pStr[i];
+ if (wc == '.') {
+ break;
+ }
+ if ((wc == L'0' || wc == L' ' || wc == '+') && nIndex == 0) {
+ continue;
+ }
+ if (wc == '-') {
+ pDst[nIndex++] = wc;
+ bMinus = TRUE;
+ continue;
+ }
+ if (wc == L'0' && nIndex == 1 && bMinus) {
+ continue;
+ }
+ pDst[nIndex++] = wc;
+ }
+ if (bMinus && nIndex == 1) {
+ pDst[nIndex++] = '0';
+ }
+ if (nIndex == 0) {
+ wsResult.ReleaseBuffer(0);
+ pDst = wsResult.GetBuffer(iCount + 1);
+ pDst[nIndex++] = '0';
+ }
+ int32_t j = 0;
+ for (j = iCount - 1; j > i; j--) {
+ FX_WCHAR wc = pStr[j];
+ if (wc != L'0' && wc != L' ') {
+ break;
+ }
+ }
+ if (j > i) {
+ pDst[nIndex++] = '.';
+ FXSYS_wcsncpy(pDst + nIndex, pStr + i + 1, j - i);
+ nIndex += j - i;
+ }
+ wsResult.ReleaseBuffer(nIndex);
+}
+FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsValue) {
+ wsValue.Empty();
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t dot_index_f = -1;
+ FX_DWORD dwFormatStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale =
+ GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t iExponent = 0;
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ int32_t iGroupLen = wsGroupSymbol.GetLength();
+ CFX_WideString wsMinus;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
+ int32_t iMinusLen = wsMinus.GetLength();
+ int cc = 0, ccf = 0;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ FX_BOOL bHavePercentSymbol = FALSE;
+ FX_BOOL bNeg = FALSE;
+ FX_BOOL bReverseParse = FALSE;
+ int32_t dot_index = 0;
+ if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) &&
+ (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ bReverseParse = TRUE;
+ }
+ bReverseParse = FALSE;
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0 && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ }
+ } else {
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 &&
+ !FXSYS_wcsncmp(str + (cc - iMinusLen + 1),
+ (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc--;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ } break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ int32_t iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ } break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ int32_t iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ } break;
+ case '8':
+ return FALSE;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 &&
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
+ iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ } break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ if (str[cc] == '-') {
+ bNeg = TRUE;
+ cc--;
+ }
+ if (cc >= 0) {
+ return FALSE;
+ }
+ }
+ if (dot_index < len && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ wsValue += '.';
+ }
+ if (!bReverseParse) {
+ ccf = dot_index_f + 1;
+ cc = (dot_index == len) ? len : dot_index + 1;
+ while (cc < len && ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ { wsValue += str[cc]; }
+ cc++;
+ ccf++;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ } else {
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 'E': {
+ if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ cc++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ iExponent = iExponent * 10 + str[cc] - '0';
+ cc++;
+ }
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf++;
+ } break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol,
+ wsSymbol);
+ int32_t iSymbolLen = wsSymbol.GetLength();
+ if (cc + iSymbolLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc += iSymbolLen;
+ ccf++;
+ } break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ int32_t iSysmbolLen = wsSymbol.GetLength();
+ if (cc + iSysmbolLen <= len &&
+ !FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsSymbol,
+ iSysmbolLen)) {
+ cc += iSysmbolLen;
+ }
+ ccf++;
+ bHavePercentSymbol = TRUE;
+ } break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ } break;
+ case ',': {
+ if (cc + iGroupLen <= len &&
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsGroupSymbol,
+ iGroupLen) == 0) {
+ cc += iGroupLen;
+ }
+ ccf++;
+ } break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ }
+ }
+ if (cc != len) {
+ return FALSE;
+ }
+ }
+ if (iExponent || bHavePercentSymbol) {
+ CFX_Decimal decimal = CFX_Decimal(wsValue);
+ if (iExponent) {
+ decimal = decimal * CFX_Decimal(FXSYS_pow(10, (FX_FLOAT)iExponent));
+ }
+ if (bHavePercentSymbol) {
+ decimal = decimal / CFX_Decimal(100);
+ }
+ wsValue = decimal;
+ }
+ if (bNeg) {
+ wsValue = CFX_WideStringC('-') + wsValue;
+ }
+ return TRUE;
+}
+FX_DATETIMETYPE CFX_FormatString::GetDateTimeFormat(
+ const CFX_WideString& wsPattern,
+ IFX_Locale*& pLocale,
+ CFX_WideString& wsDatePattern,
+ CFX_WideString& wsTimePattern) {
+ pLocale = NULL;
+ CFX_WideString wsTempPattern;
+ FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
+ int32_t ccf = 0;
+ int32_t iLenf = wsPattern.GetLength();
+ const FX_WCHAR* pStr = (const FX_WCHAR*)wsPattern;
+ int32_t iFindCategory = 0;
+ FX_BOOL bBraceOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ int32_t iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsTempPattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBraceOpen && iFindCategory != 3 &&
+ FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' &&
+ pStr[ccf] != '(') {
+ if (pStr[ccf] == 'T') {
+ wsDatePattern = wsPattern.Left(ccf);
+ wsTimePattern = wsPattern.Right(wsPattern.GetLength() - ccf);
+ wsTimePattern.SetAt(0, ' ');
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return FX_DATETIMETYPE_DateTime;
+ }
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ if (!(iFindCategory & 1) && wsCategory == FX_WSTRC(L"date")) {
+ iFindCategory |= 1;
+ eCategory = FX_LOCALECATEGORY_Date;
+ if (iFindCategory & 2) {
+ iFindCategory = 4;
+ }
+ } else if (!(iFindCategory & 2) && wsCategory == FX_WSTRC(L"time")) {
+ iFindCategory |= 2;
+ eCategory = FX_LOCALECATEGORY_Time;
+ } else if (wsCategory == FX_WSTRC(L"datetime")) {
+ iFindCategory = 3;
+ eCategory = FX_LOCALECATEGORY_DateTime;
+ } else {
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBraceOpen = TRUE;
+ break;
+ } else if (pStr[ccf] == '.') {
+ CFX_WideString wsSubCategory;
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
+ wsSubCategory += pStr[ccf++];
+ }
+ FX_DWORD dwSubHash =
+ FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
+ FX_LOCALEDATETIMESUBCATEGORY eSubCategory =
+ FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ for (int32_t i = 0; i < g_iFXLocaleDateTimeSubCatCount; i++) {
+ if (g_FXLocaleDateTimeSubCatData[i].uHash == dwSubHash) {
+ eSubCategory =
+ (FX_LOCALEDATETIMESUBCATEGORY)g_FXLocaleDateTimeSubCatData[i]
+ .eSubCategory;
+ break;
+ }
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ FXSYS_assert(pLocale != NULL);
+ switch (eCategory) {
+ case FX_LOCALECATEGORY_Date:
+ pLocale->GetDatePattern(eSubCategory, wsDatePattern);
+ wsDatePattern = wsTempPattern + wsDatePattern;
+ break;
+ case FX_LOCALECATEGORY_Time:
+ pLocale->GetTimePattern(eSubCategory, wsTimePattern);
+ wsTimePattern = wsTempPattern + wsTimePattern;
+ break;
+ case FX_LOCALECATEGORY_DateTime:
+ pLocale->GetDatePattern(eSubCategory, wsDatePattern);
+ wsDatePattern = wsTempPattern + wsDatePattern;
+ pLocale->GetTimePattern(eSubCategory, wsTimePattern);
+ break;
+ default:
+ break;
+ }
+ wsTempPattern.Empty();
+ continue;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] == '}') {
+ bBraceOpen = FALSE;
+ if (!wsTempPattern.IsEmpty()) {
+ if (eCategory == FX_LOCALECATEGORY_Time) {
+ wsTimePattern = wsTempPattern;
+ } else if (eCategory == FX_LOCALECATEGORY_Date) {
+ wsDatePattern = wsTempPattern;
+ }
+ wsTempPattern.Empty();
+ }
+ } else {
+ wsTempPattern += pStr[ccf];
+ }
+ ccf++;
+ }
+ if (!wsTempPattern.IsEmpty()) {
+ if (eCategory == FX_LOCALECATEGORY_Date) {
+ wsDatePattern += wsTempPattern;
+ } else {
+ wsTimePattern += wsTempPattern;
+ }
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ if (!iFindCategory) {
+ wsTimePattern.Empty();
+ wsDatePattern = wsPattern;
+ }
+ return (FX_DATETIMETYPE)iFindCategory;
+}
+static FX_BOOL FX_ParseLocaleDate(const CFX_WideString& wsDate,
+ const CFX_WideString& wsDatePattern,
+ IFX_Locale* pLocale,
+ CFX_Unitime& datetime,
+ int32_t& cc) {
+ int32_t year = 1900;
+ int32_t month = 1;
+ int32_t day = 1;
+ int32_t ccf = 0;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsDate;
+ int32_t len = wsDate.GetLength();
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsDatePattern;
+ int32_t lenf = wsDatePattern.GetLength();
+ while (cc < len && ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ day = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ day = day * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ day = str[cc++] - '0';
+ if (cc < len) {
+ day = day * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
+ int i = 0;
+ while (cc < len && i < 3 && FX_IsDigit(str[cc])) {
+ cc++;
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
+ cc += 3;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ month = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ month = month * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ month = str[cc++] - '0';
+ if (cc < len) {
+ month = month * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
+ CFX_WideString wsMonthNameAbbr;
+ FX_WORD i = 0;
+ for (; i < 12; i++) {
+ pLocale->GetMonthName(i, wsMonthNameAbbr, TRUE);
+ if (wsMonthNameAbbr.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((const FX_WCHAR*)wsMonthNameAbbr, str + cc,
+ wsMonthNameAbbr.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsMonthNameAbbr.GetLength();
+ month = i + 1;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
+ CFX_WideString wsMonthName;
+ FX_WORD i = 0;
+ for (; i < 12; i++) {
+ pLocale->GetMonthName(i, wsMonthName, FALSE);
+ if (wsMonthName.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((const FX_WCHAR*)wsMonthName, str + cc,
+ wsMonthName.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsMonthName.GetLength();
+ month = i + 1;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
+ CFX_WideString wsDayNameAbbr;
+ FX_WORD i = 0;
+ for (; i < 7; i++) {
+ pLocale->GetDayName(i, wsDayNameAbbr, TRUE);
+ if (wsDayNameAbbr.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((const FX_WCHAR*)wsDayNameAbbr, str + cc,
+ wsDayNameAbbr.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsDayNameAbbr.GetLength();
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
+ CFX_WideString wsDayName;
+ int32_t i = 0;
+ for (; i < 7; i++) {
+ pLocale->GetDayName(i, wsDayName, FALSE);
+ if (wsDayName == L"") {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((const FX_WCHAR*)wsDayName, str + cc,
+ wsDayName.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsDayName.GetLength();
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
+ cc += 2;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
+ if (cc + 2 > len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = str[cc++] - '0';
+ if (cc >= len || !FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = year * 10 + str[cc++] - '0';
+ if (year <= 29) {
+ year += 2000;
+ } else {
+ year += 1900;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
+ int i = 0;
+ year = 0;
+ if (cc + 4 > len) {
+ return FALSE;
+ }
+ while (i < 4) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = year * 10 + str[cc] - '0';
+ cc++;
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
+ cc += 2;
+ }
+ }
+ if (cc < len) {
+ return FALSE;
+ }
+ CFX_Unitime ut;
+ ut.Set(year, month, day);
+ datetime = datetime + ut;
+ return cc;
+}
+static void FX_ResolveZone(uint8_t& wHour,
+ uint8_t& wMinute,
+ FX_TIMEZONE tzDiff,
+ IFX_Locale* pLocale) {
+ int32_t iMinuteDiff = wHour * 60 + wMinute;
+ FX_TIMEZONE tzLocale;
+ pLocale->GetTimeZone(tzLocale);
+ iMinuteDiff += tzLocale.tzHour * 60 +
+ (tzLocale.tzHour < 0 ? -tzLocale.tzMinute : tzLocale.tzMinute);
+ iMinuteDiff -= tzDiff.tzHour * 60 +
+ (tzDiff.tzHour < 0 ? -tzDiff.tzMinute : tzDiff.tzMinute);
+ while (iMinuteDiff > 1440) {
+ iMinuteDiff -= 1440;
+ }
+ while (iMinuteDiff < 0) {
+ iMinuteDiff += 1440;
+ }
+ wHour = iMinuteDiff / 60;
+ wMinute = iMinuteDiff % 60;
+}
+static FX_BOOL FX_ParseLocaleTime(const CFX_WideString& wsTime,
+ const CFX_WideString& wsTimePattern,
+ IFX_Locale* pLocale,
+ CFX_Unitime& datetime,
+ int32_t& cc) {
+ uint8_t hour = 0;
+ uint8_t minute = 0;
+ uint8_t second = 0;
+ FX_WORD millisecond = 0;
+ int32_t ccf = 0;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsTime;
+ int len = wsTime.GetLength();
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsTimePattern;
+ int lenf = wsTimePattern.GetLength();
+ FX_BOOL bHasA = FALSE;
+ FX_BOOL bPM = FALSE;
+ while (cc < len && ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len ||
+ FXSYS_wcsncmp(str + cc, (const FX_WCHAR*)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) == -1) {
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'H', '1') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'h', '1') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ hour = hour * 10 + str[cc++] - '0';
+ }
+ if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1') && hour == 24) {
+ hour = 0;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'H', '2') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'h', '2') ||
+ dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = hour * 10 + str[cc++] - '0';
+ if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2') && hour == 24) {
+ hour = 0;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ minute = minute * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = minute * 10 + str[cc++] - '0';
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ second = second * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = second * 10 + str[cc++] - '0';
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
+ if (cc + 3 >= len) {
+ return FALSE;
+ }
+ int i = 0;
+ while (i < 3) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ millisecond = millisecond * 10 + str[cc++] - '0';
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
+ CFX_WideString wsAM;
+ pLocale->GetMeridiemName(wsAM, TRUE);
+ CFX_WideString wsPM;
+ pLocale->GetMeridiemName(wsPM, FALSE);
+ if ((cc + wsAM.GetLength() <= len) &&
+ (CFX_WideStringC(str + cc, wsAM.GetLength()) == wsAM)) {
+ cc += wsAM.GetLength();
+ bHasA = TRUE;
+ } else if ((cc + wsPM.GetLength() <= len) &&
+ (CFX_WideStringC(str + cc, wsPM.GetLength()) == wsPM)) {
+ cc += wsPM.GetLength();
+ bHasA = TRUE;
+ bPM = TRUE;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
+ if (cc + 3 > len) {
+ continue;
+ }
+ FX_DWORD dwHash = str[cc++];
+ dwHash = (dwHash << 8) | str[cc++];
+ dwHash = (dwHash << 8) | str[cc++];
+ if (dwHash == FXBSTR_ID(0, 'G', 'M', 'T')) {
+ FX_TIMEZONE tzDiff;
+ tzDiff.tzHour = 0;
+ tzDiff.tzMinute = 0;
+ if (cc < len && (str[cc] == '-' || str[cc] == '+')) {
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ }
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ } else {
+ FX_LPCLOCALETIMEZONEINFO pTimeZoneInfo = NULL;
+ int32_t iStart = 0, iEnd = g_iFXLocaleTimeZoneCount - 1;
+ do {
+ int32_t iMid = (iStart + iEnd) / 2;
+ FX_LPCLOCALETIMEZONEINFO pInfo = g_FXLocaleTimeZoneData + iMid;
+ if (dwHash == pInfo->uHash) {
+ pTimeZoneInfo = pInfo;
+ break;
+ } else if (dwHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ if (pTimeZoneInfo) {
+ hour += pTimeZoneInfo->iHour;
+ minute += pTimeZoneInfo->iHour > 0 ? pTimeZoneInfo->iMinute
+ : -pTimeZoneInfo->iMinute;
+ }
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
+ if (str[cc] != 'Z') {
+ FX_TIMEZONE tzDiff;
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ } else {
+ cc++;
+ }
+ }
+ }
+ if (bHasA) {
+ if (bPM) {
+ hour += 12;
+ if (hour == 24) {
+ hour = 12;
+ }
+ } else {
+ if (hour == 12) {
+ hour = 0;
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(0, 0, 0, hour, minute, second, millisecond);
+ datetime = datetime + ut;
+ return cc;
+}
+FX_BOOL CFX_FormatString::ParseDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ FX_DATETIMETYPE eDateTimeType,
+ CFX_Unitime& dtValue) {
+ dtValue.Set(0);
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory =
+ GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ eCategory = eDateTimeType;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_TimeDate) {
+ int32_t iStart = 0;
+ if (!FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue,
+ iStart)) {
+ return FALSE;
+ }
+ if (!FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue,
+ iStart)) {
+ return FALSE;
+ }
+ } else {
+ int32_t iStart = 0;
+ if ((eCategory & FX_DATETIMETYPE_Date) &&
+ !FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue,
+ iStart)) {
+ return FALSE;
+ }
+ if ((eCategory & FX_DATETIMETYPE_Time) &&
+ !FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue,
+ iStart)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::ParseZero(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern) {
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
+ int32_t iText = 0, iPattern = 0;
+ const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
+ int32_t iLenText = wsSrcText.GetLength();
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ if (pStrPattern[iPattern] == '\'') {
+ CFX_WideString wsLiteral =
+ FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText ||
+ FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ continue;
+ } else if (pStrPattern[iPattern] != pStrText[iText]) {
+ return FALSE;
+ } else {
+ iText++;
+ iPattern++;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::ParseNull(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern) {
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
+ int32_t iText = 0, iPattern = 0;
+ const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
+ int32_t iLenText = wsSrcText.GetLength();
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ if (pStrPattern[iPattern] == '\'') {
+ CFX_WideString wsLiteral =
+ FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ int32_t iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText ||
+ FXSYS_wcsncmp(pStrText + iText, (const FX_WCHAR*)wsLiteral,
+ iLiteralLen)) {
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ continue;
+ } else if (pStrPattern[iPattern] != pStrText[iText]) {
+ return FALSE;
+ } else {
+ iText++;
+ iPattern++;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::FormatText(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t iLenText = wsSrcText.GetLength();
+ if (iLenText == 0) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
+ int32_t iText = 0, iPattern = 0;
+ const FX_WCHAR* pStrText = (const FX_WCHAR*)wsSrcText;
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ switch (pStrPattern[iPattern]) {
+ case '\'': {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ break;
+ }
+ case 'A':
+ if (iText >= iLenText || !FX_IsAlpha(pStrText[iText])) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case 'X':
+ if (iText >= iLenText) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case 'O':
+ case '0':
+ if (iText >= iLenText ||
+ (!FX_IsDigit(pStrText[iText]) && !FX_IsAlpha(pStrText[iText]))) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case '9':
+ if (iText >= iLenText || !FX_IsDigit(pStrText[iText])) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ default:
+ wsOutput += pStrPattern[iPattern++];
+ break;
+ }
+ }
+ return iText == iLenText;
+}
+static int32_t FX_GetNumTrailingLimit(const CFX_WideString& wsFormat,
+ int iDotPos,
+ FX_BOOL& bTrimTailZeros) {
+ if (iDotPos < 0) {
+ return 0;
+ }
+ int32_t iCount = wsFormat.GetLength();
+ int32_t iTreading = 0;
+ for (iDotPos++; iDotPos < iCount; iDotPos++) {
+ FX_WCHAR wc = wsFormat[iDotPos];
+ if (wc == L'z' || wc == L'9' || wc == 'Z') {
+ iTreading++;
+ bTrimTailZeros = (wc == L'9' ? FALSE : TRUE);
+ }
+ }
+ return iTreading;
+}
+FX_BOOL CFX_FormatString::FormatStrNum(const CFX_WideStringC& wsInputNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsInputNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t dot_index_f = -1;
+ FX_DWORD dwNumStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale =
+ GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t cc = 0, ccf = 0;
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ CFX_WideString wsSrcNum = wsInputNum;
+ wsSrcNum.TrimLeft('0');
+ if (wsSrcNum.IsEmpty() || wsSrcNum[0] == '.') {
+ wsSrcNum.Insert(0, '0');
+ }
+ CFX_Decimal decimal = CFX_Decimal(wsSrcNum);
+ if (dwNumStyle & FX_NUMSTYLE_Percent) {
+ decimal = decimal * CFX_Decimal(100);
+ wsSrcNum = decimal;
+ }
+ int32_t exponent = 0;
+ if (dwNumStyle & FX_NUMSTYLE_Exponent) {
+ int fixed_count = 0;
+ while (ccf < dot_index_f) {
+ switch (strf[ccf]) {
+ case '\'':
+ FX_GetLiteralText(strf, ccf, dot_index_f);
+ break;
+ case '9':
+ case 'z':
+ case 'Z':
+ fixed_count++;
+ break;
+ }
+ ccf++;
+ }
+ int threshold = 1;
+ while (fixed_count > 1) {
+ threshold *= 10;
+ fixed_count--;
+ }
+ if (decimal != CFX_Decimal(0)) {
+ if (decimal < CFX_Decimal(threshold)) {
+ decimal = decimal * CFX_Decimal(10);
+ exponent = -1;
+ while (decimal < CFX_Decimal(threshold)) {
+ decimal = decimal * CFX_Decimal(10);
+ exponent -= 1;
+ }
+ } else if (decimal > CFX_Decimal(threshold)) {
+ threshold *= 10;
+ while (decimal > CFX_Decimal(threshold)) {
+ decimal = decimal / CFX_Decimal(10);
+ exponent += 1;
+ }
+ }
+ }
+ }
+ FX_BOOL bTrimTailZeros = FALSE;
+ int32_t iTreading =
+ FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
+ int32_t scale = decimal.GetScale();
+ if (iTreading < scale) {
+ decimal.SetScale(iTreading);
+ wsSrcNum = decimal;
+ }
+ if (bTrimTailZeros && scale > 0 && iTreading > 0) {
+ wsSrcNum.TrimRight(L"0");
+ wsSrcNum.TrimRight(L".");
+ }
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_BOOL bNeg = FALSE;
+ if (wsSrcNum[0] == '-') {
+ bNeg = TRUE;
+ wsSrcNum.Delete(0, 1);
+ }
+ FX_BOOL bAddNeg = FALSE;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ int dot_index = wsSrcNum.Find('.');
+ if (dot_index == -1) {
+ dot_index = len;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0) {
+ switch (strf[ccf]) {
+ case '9':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L'0') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ if (str[0] != '0') {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ if (str[0] == '0') {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ } else {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format(L"E%+d", exponent);
+ wsOutput = wsExp + wsOutput;
+ }
+ ccf--;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (bNeg) {
+ wsOutput = L"db" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (bNeg) {
+ wsOutput = L"DB" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case ',':
+ if (cc >= 0) {
+ wsOutput = wsGroupSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput = L"(" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ bAddNeg = TRUE;
+ ccf--;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput = L")" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf--;
+ break;
+ case '\'':
+ wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
+ ccf--;
+ break;
+ default:
+ wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ int nPos = dot_index % 3;
+ wsOutput.Empty();
+ for (int32_t i = 0; i < dot_index; i++) {
+ if (i % 3 == nPos && i != 0) {
+ wsOutput += wsGroupSymbol;
+ }
+ wsOutput += wsSrcNum[i];
+ }
+ if (dot_index < len) {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+ wsOutput += wsSymbol;
+ wsOutput += wsSrcNum.Right(len - dot_index - 1);
+ }
+ if (bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return FALSE;
+ }
+ if (dot_index_f == wsNumFormat.GetLength()) {
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return TRUE;
+ }
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ if (strf[dot_index_f] == 'V') {
+ wsOutput += wsDotSymbol;
+ } else if (strf[dot_index_f] == '.') {
+ if (dot_index < len) {
+ wsOutput += wsDotSymbol;
+ } else {
+ if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
+ wsOutput += wsDotSymbol;
+ }
+ }
+ }
+ ccf = dot_index_f + 1;
+ cc = dot_index + 1;
+ while (ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'':
+ wsOutput += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ break;
+ case '9':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'z':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format(L"E%+d", exponent);
+ wsOutput += wsExp;
+ }
+ ccf++;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (bNeg) {
+ wsOutput += L"db";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (bNeg) {
+ wsOutput += L"DB";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ } break;
+ case ',':
+ wsOutput += wsGroupSymbol;
+ ccf++;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput += '(';
+ } else {
+ wsOutput += ' ';
+ }
+ bAddNeg = TRUE;
+ ccf++;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput += ')';
+ } else {
+ wsOutput += ' ';
+ }
+ ccf++;
+ break;
+ default:
+ ccf++;
+ }
+ }
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput =
+ wsMinusymbol + wsOutput[0] + wsOutput.Mid(1, wsOutput.GetLength() - 1);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatLCNumeric(CFX_LCNumeric& lcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ int32_t dot_index_f = -1;
+ FX_DWORD dwNumStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale =
+ GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ int32_t cc = 0, ccf = 0;
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ double dbOrgRaw = lcNum.GetDouble();
+ double dbRetValue = dbOrgRaw;
+ if (dwNumStyle & FX_NUMSTYLE_Percent) {
+ dbRetValue *= 100;
+ }
+ int32_t exponent = 0;
+ if (dwNumStyle & FX_NUMSTYLE_Exponent) {
+ int fixed_count = 0;
+ while (ccf < dot_index_f) {
+ switch (strf[ccf]) {
+ case '\'':
+ FX_GetLiteralText(strf, ccf, dot_index_f);
+ break;
+ case '9':
+ case 'z':
+ case 'Z':
+ fixed_count++;
+ break;
+ }
+ ccf++;
+ }
+ int threshold = 1;
+ while (fixed_count > 1) {
+ threshold *= 10;
+ fixed_count--;
+ }
+ if (dbRetValue != 0) {
+ if (dbRetValue < threshold) {
+ dbRetValue *= 10;
+ exponent = -1;
+ while (dbRetValue < threshold) {
+ dbRetValue *= 10;
+ exponent -= 1;
+ }
+ } else if (dbRetValue > threshold) {
+ threshold *= 10;
+ while (dbRetValue > threshold) {
+ dbRetValue /= 10;
+ exponent += 1;
+ }
+ }
+ }
+ }
+ if (dwNumStyle & (FX_NUMSTYLE_Percent | FX_NUMSTYLE_Exponent)) {
+ lcNum = CFX_LCNumeric(dbRetValue);
+ }
+ FX_BOOL bTrimTailZeros = FALSE;
+ int32_t iTreading =
+ FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
+ CFX_WideString wsNumeric = lcNum.ToString(iTreading, bTrimTailZeros);
+ if (wsNumeric.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_BOOL bNeg = FALSE;
+ if (wsNumeric[0] == '-') {
+ bNeg = TRUE;
+ wsNumeric.Delete(0, 1);
+ }
+ FX_BOOL bAddNeg = FALSE;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsNumeric;
+ int len = wsNumeric.GetLength();
+ int dot_index = wsNumeric.Find('.');
+ if (dot_index == -1) {
+ dot_index = len;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0) {
+ switch (strf[ccf]) {
+ case '9':
+ if (cc >= 0) {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L'0') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ if (lcNum.m_Integral != 0) {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (cc >= 0) {
+ if (lcNum.m_Integral == 0) {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ } else {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format(L"E%+d", exponent);
+ wsOutput = wsExp + wsOutput;
+ }
+ ccf--;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (bNeg) {
+ wsOutput = L"db" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (bNeg) {
+ wsOutput = L"DB" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case ',':
+ if (cc >= 0) {
+ wsOutput = wsGroupSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput = L"(" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ bAddNeg = TRUE;
+ ccf--;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput = L")" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf--;
+ break;
+ case '\'':
+ wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
+ ccf--;
+ break;
+ default:
+ wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ int nPos = dot_index % 3;
+ wsOutput.Empty();
+ for (int32_t i = 0; i < dot_index; i++) {
+ if (i % 3 == nPos && i != 0) {
+ wsOutput += wsGroupSymbol;
+ }
+ wsOutput += wsNumeric[i];
+ }
+ if (dot_index < len) {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+ wsOutput += wsSymbol;
+ wsOutput += wsNumeric.Right(len - dot_index - 1);
+ }
+ if (bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return FALSE;
+ }
+ if (dot_index_f == wsNumFormat.GetLength()) {
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return TRUE;
+ }
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ if (strf[dot_index_f] == 'V') {
+ wsOutput += wsDotSymbol;
+ } else if (strf[dot_index_f] == '.') {
+ if (dot_index < len) {
+ wsOutput += wsDotSymbol;
+ } else {
+ if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
+ wsOutput += wsDotSymbol;
+ }
+ }
+ }
+ ccf = dot_index_f + 1;
+ cc = dot_index + 1;
+ while (ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'':
+ wsOutput += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ break;
+ case '9':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'z':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format(L"E%+d", exponent);
+ wsOutput += wsExp;
+ }
+ ccf++;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (bNeg) {
+ wsOutput += L"db";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (bNeg) {
+ wsOutput += L"DB";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ } break;
+ case ',':
+ wsOutput += wsGroupSymbol;
+ ccf++;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput += '(';
+ } else {
+ wsOutput += ' ';
+ }
+ bAddNeg = TRUE;
+ ccf++;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput += ')';
+ } else {
+ wsOutput += ' ';
+ }
+ ccf++;
+ break;
+ default:
+ ccf++;
+ }
+ }
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput =
+ wsOutput[0] + wsMinusymbol + wsOutput.Mid(1, wsOutput.GetLength() - 1);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ return FormatStrNum(wsSrcNum, wsPattern, wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatNum(FX_FLOAT fNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_LCNumeric lcNum(fNum);
+ return FormatLCNumeric(lcNum, wsPattern, wsOutput);
+}
+FX_BOOL FX_DateFromCanonical(const CFX_WideString& wsDate,
+ CFX_Unitime& datetime) {
+ int32_t year = 1900;
+ int32_t month = 1;
+ int32_t day = 1;
+ FX_WORD wYear = 0;
+ int cc_start = 0, cc = 0;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsDate;
+ int len = wsDate.GetLength();
+ if (len > 10) {
+ return FALSE;
+ }
+ while (cc < len && cc < 4) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wYear = wYear * 10 + str[cc++] - '0';
+ }
+ year = wYear;
+ if (cc < 4 || wYear < 1900) {
+ return FALSE;
+ }
+ if (cc < len) {
+ if (str[cc] == '-') {
+ cc++;
+ }
+ cc_start = cc;
+ uint8_t tmpM = 0;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ tmpM = tmpM * 10 + str[cc++] - '0';
+ }
+ month = tmpM;
+ if (cc == cc_start + 1 || tmpM > 12 || tmpM < 1) {
+ return FALSE;
+ }
+ if (cc < len) {
+ if (str[cc] == '-') {
+ cc++;
+ }
+ uint8_t tmpD = 0;
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ tmpD = tmpD * 10 + str[cc++] - '0';
+ }
+ day = tmpD;
+ if (tmpD < 1) {
+ return FALSE;
+ }
+ if ((tmpM == 1 || tmpM == 3 || tmpM == 5 || tmpM == 7 || tmpM == 8 ||
+ tmpM == 10 || tmpM == 12) &&
+ tmpD > 31) {
+ return FALSE;
+ }
+ if ((tmpM == 4 || tmpM == 6 || tmpM == 9 || tmpM == 11) && tmpD > 30) {
+ return FALSE;
+ }
+ FX_BOOL iLeapYear;
+ if ((wYear % 4 == 0 && wYear % 100 != 0) || wYear % 400 == 0) {
+ iLeapYear = TRUE;
+ } else {
+ iLeapYear = FALSE;
+ }
+ if ((iLeapYear && tmpM == 2 && tmpD > 29) ||
+ (!iLeapYear && tmpM == 2 && tmpD > 28)) {
+ return FALSE;
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(year, month, day);
+ datetime = datetime + ut;
+ return TRUE;
+}
+FX_BOOL FX_TimeFromCanonical(const CFX_WideStringC& wsTime,
+ CFX_Unitime& datetime,
+ IFX_Locale* pLocale) {
+ if (wsTime.GetLength() == 0) {
+ return FALSE;
+ }
+ uint8_t hour = 0;
+ uint8_t minute = 0;
+ uint8_t second = 0;
+ FX_WORD millisecond = 0;
+ int cc_start = 0, cc = cc_start;
+ const FX_WCHAR* str = (const FX_WCHAR*)wsTime.GetPtr();
+ int len = wsTime.GetLength();
+ while (cc < len && cc < 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = hour * 10 + str[cc++] - '0';
+ }
+ if (cc < 2 || hour >= 24) {
+ return FALSE;
+ }
+ if (cc < len) {
+ if (str[cc] == ':') {
+ cc++;
+ }
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = minute * 10 + str[cc++] - '0';
+ }
+ if (cc == cc_start + 1 || minute >= 60) {
+ return FALSE;
+ }
+ if (cc < len) {
+ if (str[cc] == ':') {
+ cc++;
+ }
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = second * 10 + str[cc++] - '0';
+ }
+ if (cc == cc_start + 1 || second >= 60) {
+ return FALSE;
+ }
+ if (cc < len) {
+ if (str[cc] == '.') {
+ cc++;
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 3) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ millisecond = millisecond * 10 + str[cc++] - '0';
+ }
+ if (cc < cc_start + 3 || millisecond >= 1000) {
+ return FALSE;
+ }
+ }
+ if (cc < len) {
+ FX_TIMEZONE tzDiff;
+ tzDiff.tzHour = 0;
+ tzDiff.tzMinute = 0;
+ if (str[cc] != 'Z') {
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ }
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ }
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(0, 0, 0, hour, minute, second, millisecond);
+ datetime = datetime + ut;
+ return TRUE;
+}
+static FX_WORD FX_GetSolarMonthDays(FX_WORD year, FX_WORD month) {
+ if (month % 2) {
+ return 31;
+ } else if (month == 2) {
+ return FX_IsLeapYear(year) ? 29 : 28;
+ }
+ return 30;
+}
+static FX_WORD FX_GetWeekDay(FX_WORD year, FX_WORD month, FX_WORD day) {
+ FX_WORD g_month_day[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
+ FX_WORD nDays =
+ (year - 1) % 7 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
+ nDays += g_month_day[month - 1] + day;
+ if (FX_IsLeapYear(year) && month > 2) {
+ nDays++;
+ }
+ return nDays % 7;
+}
+static FX_WORD FX_GetWeekOfMonth(FX_WORD year, FX_WORD month, FX_WORD day) {
+ FX_WORD week_day = FX_GetWeekDay(year, month, 1);
+ FX_WORD week_index = 0;
+ week_index += day / 7;
+ day = day % 7;
+ if (week_day + day > 7) {
+ week_index++;
+ }
+ return week_index;
+}
+static FX_WORD FX_GetWeekOfYear(FX_WORD year, FX_WORD month, FX_WORD day) {
+ FX_WORD nDays = 0;
+ for (FX_WORD i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ FX_WORD week_day = FX_GetWeekDay(year, 1, 1);
+ FX_WORD week_index = 1;
+ week_index += nDays / 7;
+ nDays = nDays % 7;
+ if (week_day + nDays > 7) {
+ week_index++;
+ }
+ return week_index;
+}
+static FX_BOOL FX_DateFormat(const CFX_WideString& wsDatePattern,
+ IFX_Locale* pLocale,
+ const CFX_Unitime& datetime,
+ CFX_WideString& wsResult) {
+ FX_BOOL bRet = TRUE;
+ int32_t year = datetime.GetYear();
+ uint8_t month = datetime.GetMonth();
+ uint8_t day = datetime.GetDay();
+ int32_t ccf = 0;
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsDatePattern;
+ int32_t lenf = wsDatePattern.GetLength();
+ while (ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ wsResult += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
+ wsResult += strf[ccf++];
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
+ CFX_WideString wsDay;
+ wsDay.Format(L"%d", day);
+ wsResult += wsDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
+ CFX_WideString wsDay;
+ wsDay.Format(L"%02d", day);
+ wsResult += wsDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
+ FX_WORD nDays = 0;
+ for (int i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ CFX_WideString wsDays;
+ wsDays.Format(L"%d", nDays);
+ wsResult += wsDays;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
+ FX_WORD nDays = 0;
+ for (int i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ CFX_WideString wsDays;
+ wsDays.Format(L"%03d", nDays);
+ wsResult += wsDays;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ CFX_WideString wsMonth;
+ wsMonth.Format(L"%d", month);
+ wsResult += wsMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ CFX_WideString wsMonth;
+ wsMonth.Format(L"%02d", month);
+ wsResult += wsMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
+ CFX_WideString wsTemp;
+ pLocale->GetMonthName(month - 1, wsTemp, TRUE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
+ CFX_WideString wsTemp;
+ pLocale->GetMonthName(month - 1, wsTemp, FALSE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsWeekDay;
+ wsWeekDay.Format(L"%d", wWeekDay + 1);
+ wsResult += wsWeekDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsTemp;
+ pLocale->GetDayName(wWeekDay, wsTemp, TRUE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ if (pLocale) {
+ CFX_WideString wsTemp;
+ pLocale->GetDayName(wWeekDay, wsTemp, FALSE);
+ wsResult += wsTemp;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsWeekDay;
+ wsWeekDay.Format(L"%d", wWeekDay ? wWeekDay : 7);
+ wsResult += wsWeekDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
+ CFX_WideString wsTemp;
+ pLocale->GetEraName(wsTemp, year < 0);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
+ CFX_WideString wsYear;
+ wsYear.Format(L"%02d", year % 100);
+ wsResult += wsYear;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
+ CFX_WideString wsYear;
+ wsYear.Format(L"%d", year);
+ wsResult += wsYear;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
+ FX_WORD week_index = FX_GetWeekOfMonth(year, month, day);
+ CFX_WideString wsWeekInMonth;
+ wsWeekInMonth.Format(L"%d", week_index);
+ wsResult += wsWeekInMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
+ FX_WORD week_index = FX_GetWeekOfYear(year, month, day);
+ CFX_WideString wsWeekInYear;
+ wsWeekInYear.Format(L"%02d", week_index);
+ wsResult += wsWeekInYear;
+ }
+ }
+ return bRet;
+}
+static FX_BOOL FX_TimeFormat(const CFX_WideString& wsTimePattern,
+ IFX_Locale* pLocale,
+ const CFX_Unitime& datetime,
+ CFX_WideString& wsResult) {
+ FX_BOOL bGMT = FALSE;
+ FX_BOOL bRet = TRUE;
+ uint8_t hour = datetime.GetHour();
+ uint8_t minute = datetime.GetMinute();
+ uint8_t second = datetime.GetSecond();
+ FX_WORD millisecond = datetime.GetMillisecond();
+ int32_t ccf = 0;
+ const FX_WCHAR* strf = (const FX_WCHAR*)wsTimePattern;
+ int32_t lenf = wsTimePattern.GetLength();
+ FX_WORD wHour = hour;
+ FX_BOOL bPM = FALSE;
+ if (wsTimePattern.Find('A') != -1) {
+ if (wHour >= 12) {
+ bPM = TRUE;
+ }
+ }
+ while (ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ wsResult += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) < 0) {
+ wsResult += strf[ccf++];
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'h', '1')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format(L"%d", wHour == 0 ? 12 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'h', '2')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format(L"%02d", wHour == 0 ? 12 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
+ CFX_WideString wsHour;
+ wsHour.Format(L"%d", wHour == 0 ? 24 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
+ CFX_WideString wsHour;
+ wsHour.Format(L"%02d", wHour == 0 ? 24 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format(L"%d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '1')) {
+ CFX_WideString wsHour;
+ wsHour.Format(L"%d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format(L"%02d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '2')) {
+ CFX_WideString wsHour;
+ wsHour.Format(L"%02d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ CFX_WideString wsMinute;
+ wsMinute.Format(L"%d", minute);
+ wsResult += wsMinute;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ CFX_WideString wsMinute;
+ wsMinute.Format(L"%02d", minute);
+ wsResult += wsMinute;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
+ CFX_WideString wsSecond;
+ wsSecond.Format(L"%d", second);
+ wsResult += wsSecond;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
+ CFX_WideString wsSecond;
+ wsSecond.Format(L"%02d", second);
+ wsResult += wsSecond;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
+ CFX_WideString wsMilliseconds;
+ wsMilliseconds.Format(L"%03d", millisecond);
+ wsResult += wsMilliseconds;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
+ CFX_WideString wsMeridiem;
+ pLocale->GetMeridiemName(wsMeridiem, !bPM);
+ wsResult += wsMeridiem;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
+ wsResult += FX_WSTRC(L"GMT");
+ FX_TIMEZONE tz;
+ pLocale->GetTimeZone(tz);
+ if (!bGMT && (tz.tzHour != 0 || tz.tzMinute != 0)) {
+ if (tz.tzHour < 0) {
+ wsResult += FX_WSTRC(L"-");
+ } else {
+ wsResult += FX_WSTRC(L"+");
+ }
+ CFX_WideString wsTimezone;
+ wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
+ wsResult += wsTimezone;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
+ FX_TIMEZONE tz;
+ pLocale->GetTimeZone(tz);
+ if (!bGMT && tz.tzHour != 0 && tz.tzMinute != 0) {
+ if (tz.tzHour < 0) {
+ wsResult += FX_WSTRC(L"-");
+ } else {
+ wsResult += FX_WSTRC(L"+");
+ }
+ CFX_WideString wsTimezone;
+ wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
+ wsResult += wsTimezone;
+ }
+ }
+ }
+ return bRet;
+}
+static FX_BOOL FX_FormatDateTime(const CFX_Unitime& dt,
+ const CFX_WideString& wsDatePattern,
+ const CFX_WideString& wsTimePattern,
+ FX_BOOL bDateFirst,
+ IFX_Locale* pLocale,
+ CFX_WideString& wsOutput) {
+ FX_BOOL bRet = TRUE;
+ CFX_WideString wsDateOut, wsTimeOut;
+ if (!wsDatePattern.IsEmpty()) {
+ bRet &= FX_DateFormat(wsDatePattern, pLocale, dt, wsDateOut);
+ }
+ if (!wsTimePattern.IsEmpty()) {
+ bRet &= FX_TimeFormat(wsTimePattern, pLocale, dt, wsTimeOut);
+ }
+ wsOutput = bDateFirst ? wsDateOut + wsTimeOut : wsTimeOut + wsDateOut;
+ return bRet;
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory =
+ GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (pLocale == NULL || eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ CFX_Unitime dt(0);
+ int32_t iT = wsSrcDateTime.Find(L"T");
+ if (iT < 0) {
+ if (eCategory == FX_DATETIMETYPE_Date) {
+ FX_DateFromCanonical(wsSrcDateTime, dt);
+ } else if (eCategory == FX_DATETIMETYPE_Time) {
+ FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale);
+ }
+ } else {
+ FX_DateFromCanonical(wsSrcDateTime.Left(iT), dt);
+ FX_TimeFromCanonical(
+ wsSrcDateTime.Right(wsSrcDateTime.GetLength() - iT - 1), dt, pLocale);
+ }
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern,
+ eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
+ wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput,
+ FX_DATETIMETYPE eDateTimeType) {
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory =
+ GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ if (eDateTimeType == FX_DATETIMETYPE_Time) {
+ wsTimePattern = wsDatePattern;
+ wsDatePattern.Empty();
+ }
+ eCategory = eDateTimeType;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ CFX_Unitime dt(0);
+ int32_t iT = wsSrcDateTime.Find(L"T");
+ if (iT < 0) {
+ if (eCategory == FX_DATETIMETYPE_Date &&
+ FX_DateFromCanonical(wsSrcDateTime, dt)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale,
+ wsOutput);
+ } else if (eCategory == FX_DATETIMETYPE_Time &&
+ FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale,
+ wsOutput);
+ }
+ } else {
+ CFX_WideStringC wsSrcDate((const FX_WCHAR*)wsSrcDateTime, iT);
+ CFX_WideStringC wsSrcTime((const FX_WCHAR*)wsSrcDateTime + iT + 1,
+ wsSrcDateTime.GetLength() - iT - 1);
+ if (wsSrcDate.IsEmpty() || wsSrcTime.IsEmpty()) {
+ return FALSE;
+ }
+ if (FX_DateFromCanonical(wsSrcDate, dt) &&
+ FX_TimeFromCanonical(wsSrcTime, dt, pLocale)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern,
+ eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
+ wsOutput);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_Unitime& dt,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory =
+ GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ return FX_FormatDateTime(dt, wsPattern, wsTimePattern,
+ eCategory != FX_DATETIMETYPE_TimeDate, pLocale,
+ wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatZero(const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
+ int32_t iPattern = 0;
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ continue;
+ } else {
+ wsOutput += pStrPattern[iPattern++];
+ continue;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatNull(const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput) {
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
+ int32_t iPattern = 0;
+ const FX_WCHAR* pStrPattern = (const FX_WCHAR*)wsTextFormat;
+ int32_t iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ continue;
+ } else {
+ wsOutput += pStrPattern[iPattern++];
+ continue;
+ }
+ }
+ return TRUE;
+}
+IFX_Locale* CFX_FormatString::GetPatternLocale(
+ const CFX_WideStringC& wsLocale) {
+ if (m_bUseLCID) {
+ }
+ return m_pLocaleMgr->GetLocaleByName(wsLocale);
+}
+#define FXMATH_DECIMAL_SCALELIMIT 0x1c
+#define FXMATH_DECIMAL_NEGMASK (0x80000000L)
+#define FXMATH_DECIMAL_FORCEBOOL(x) (!(!(x)))
+#define FXMATH_DECIMAL_MAKEFLAGS(NEG, SCALE) \
+ (((SCALE) << 0x10) | ((NEG) ? FXMATH_DECIMAL_NEGMASK : 0))
+#define FXMATH_DECIMAL_FLAGS2NEG(FLAGS) \
+ FXMATH_DECIMAL_FORCEBOOL((FLAGS)&FXMATH_DECIMAL_NEGMASK)
+#define FXMATH_DECIMAL_FLAGS2SCALE(FLAGS) \
+ ((uint8_t)(((FLAGS) & ~FXMATH_DECIMAL_NEGMASK) >> 0x10))
+#define FXMATH_DECIMAL_RSHIFT32BIT(x) ((x) >> 0x10 >> 0x10)
+#define FXMATH_DECIMAL_LSHIFT32BIT(x) ((x) << 0x10 << 0x10)
+static inline uint8_t fxmath_decimal_helper_div10(uint64_t& phi,
+ uint64_t& pmid,
+ uint64_t& plo) {
+ uint8_t retVal;
+ pmid += FXMATH_DECIMAL_LSHIFT32BIT(phi % 0xA);
+ phi /= 0xA;
+ plo += FXMATH_DECIMAL_LSHIFT32BIT(pmid % 0xA);
+ pmid /= 0xA;
+ retVal = plo % 0xA;
+ plo /= 0xA;
+ return retVal;
+}
+static inline uint8_t fxmath_decimal_helper_div10_any(uint64_t nums[],
+ uint8_t numcount) {
+ uint8_t retVal = 0;
+ for (int i = numcount - 1; i > 0; i--) {
+ nums[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(nums[i] % 0xA);
+ nums[i] /= 0xA;
+ }
+ if (numcount) {
+ retVal = nums[0] % 0xA;
+ nums[0] /= 0xA;
+ }
+ return retVal;
+}
+static inline void fxmath_decimal_helper_mul10(uint64_t& phi,
+ uint64_t& pmid,
+ uint64_t& plo) {
+ plo *= 0xA;
+ pmid = pmid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(plo);
+ plo = (uint32_t)plo;
+ phi = phi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (uint32_t)pmid;
+}
+static inline void fxmath_decimal_helper_mul10_any(uint64_t nums[],
+ uint8_t numcount) {
+ nums[0] *= 0xA;
+ for (int i = 1; i < numcount; i++) {
+ nums[i] = nums[i] * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(nums[i - 1]);
+ nums[i - 1] = (uint32_t)nums[i - 1];
+ }
+}
+static inline void fxmath_decimal_helper_normalize(uint64_t& phi,
+ uint64_t& pmid,
+ uint64_t& plo) {
+ phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (uint32_t)pmid;
+ pmid += FXMATH_DECIMAL_RSHIFT32BIT(plo);
+ plo = (uint32_t)plo;
+ phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (uint32_t)pmid;
+}
+static inline void fxmath_decimal_helper_normalize_any(uint64_t nums[],
+ uint8_t len) {
+ {
+ for (int i = len - 2; i > 0; i--) {
+ nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
+ nums[i] = (uint32_t)nums[i];
+ }
+ }
+ {
+ for (int i = 0; i < len - 1; i++) {
+ nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
+ nums[i] = (uint32_t)nums[i];
+ }
+ }
+}
+static inline int8_t fxmath_decimal_helper_raw_compare(uint32_t hi1,
+ uint32_t mid1,
+ uint32_t lo1,
+ uint32_t hi2,
+ uint32_t mid2,
+ uint32_t lo2) {
+ int8_t retVal = 0;
+ if (!retVal) {
+ retVal += (hi1 > hi2 ? 1 : (hi1 < hi2 ? -1 : 0));
+ }
+ if (!retVal) {
+ retVal += (mid1 > mid2 ? 1 : (mid1 < mid2 ? -1 : 0));
+ }
+ if (!retVal) {
+ retVal += (lo1 > lo2 ? 1 : (lo1 < lo2 ? -1 : 0));
+ }
+ return retVal;
+}
+static inline int8_t fxmath_decimal_helper_raw_compare_any(uint64_t a[],
+ uint8_t al,
+ uint64_t b[],
+ uint8_t bl) {
+ int8_t retVal = 0;
+ for (int i = std::max(al - 1, bl - 1); i >= 0; i--) {
+ uint64_t l = (i >= al ? 0 : a[i]), r = (i >= bl ? 0 : b[i]);
+ retVal += (l > r ? 1 : (l < r ? -1 : 0));
+ if (retVal) {
+ return retVal;
+ }
+ }
+ return retVal;
+}
+static inline void fxmath_decimal_helper_dec_any(uint64_t a[], uint8_t al) {
+ for (int i = 0; i < al; i++) {
+ if (a[i]--) {
+ return;
+ }
+ }
+}
+static inline void fxmath_decimal_helper_inc_any(uint64_t a[], uint8_t al) {
+ for (int i = 0; i < al; i++) {
+ a[i]++;
+ if ((uint32_t)a[i] == a[i]) {
+ return;
+ }
+ a[i] = 0;
+ }
+}
+static inline void fxmath_decimal_helper_raw_mul(uint64_t a[],
+ uint8_t al,
+ uint64_t b[],
+ uint8_t bl,
+ uint64_t c[],
+ uint8_t cl) {
+ assert(al + bl <= cl);
+ {
+ for (int i = 0; i < cl; i++) {
+ c[i] = 0;
+ }
+ }
+ {
+ for (int i = 0; i < al; i++) {
+ for (int j = 0; j < bl; j++) {
+ uint64_t m = (uint64_t)a[i] * b[j];
+ c[i + j] += (uint32_t)m;
+ c[i + j + 1] += FXMATH_DECIMAL_RSHIFT32BIT(m);
+ }
+ }
+ }
+ {
+ for (int i = 0; i < cl - 1; i++) {
+ c[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(c[i]);
+ c[i] = (uint32_t)c[i];
+ }
+ }
+ {
+ for (int i = 0; i < cl; i++) {
+ c[i] = (uint32_t)c[i];
+ }
+ }
+}
+static inline void fxmath_decimal_helper_raw_div(uint64_t a[],
+ uint8_t al,
+ uint64_t b[],
+ uint8_t bl,
+ uint64_t c[],
+ uint8_t cl) {
+ int i;
+ for (i = 0; i < cl; i++) {
+ c[i] = 0;
+ }
+ uint64_t left[16] = {0}, right[16] = {0};
+ left[0] = 0;
+ for (i = 0; i < al; i++) {
+ right[i] = a[i];
+ }
+ uint64_t tmp[16];
+ while (fxmath_decimal_helper_raw_compare_any(left, al, right, al) <= 0) {
+ uint64_t cur[16];
+ for (i = 0; i < al; i++) {
+ cur[i] = left[i] + right[i];
+ }
+ for (i = al - 1; i >= 0; i--) {
+ if (i) {
+ cur[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(cur[i] % 2);
+ }
+ cur[i] /= 2;
+ }
+ fxmath_decimal_helper_raw_mul(cur, al, b, bl, tmp, 16);
+ switch (fxmath_decimal_helper_raw_compare_any(tmp, 16, a, al)) {
+ case -1:
+ for (i = 0; i < 16; i++) {
+ left[i] = cur[i];
+ }
+ left[0]++;
+ fxmath_decimal_helper_normalize_any(left, al);
+ break;
+ case 1:
+ for (i = 0; i < 16; i++) {
+ right[i] = cur[i];
+ }
+ fxmath_decimal_helper_dec_any(right, al);
+ break;
+ case 0:
+ for (i = 0; i < std::min(al, cl); i++) {
+ c[i] = cur[i];
+ }
+ return;
+ }
+ }
+ for (i = 0; i < std::min(al, cl); i++) {
+ c[i] = left[i];
+ }
+}
+static inline FX_BOOL fxmath_decimal_helper_outofrange(uint64_t a[],
+ uint8_t al,
+ uint8_t goal) {
+ for (int i = goal; i < al; i++) {
+ if (a[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+static inline void fxmath_decimal_helper_shrinkintorange(uint64_t a[],
+ uint8_t al,
+ uint8_t goal,
+ uint8_t& scale) {
+ FX_BOOL bRoundUp = FALSE;
+ while (scale != 0 && (scale > FXMATH_DECIMAL_SCALELIMIT ||
+ fxmath_decimal_helper_outofrange(a, al, goal))) {
+ bRoundUp = fxmath_decimal_helper_div10_any(a, al) >= 5;
+ scale--;
+ }
+ if (bRoundUp) {
+ fxmath_decimal_helper_normalize_any(a, goal);
+ fxmath_decimal_helper_inc_any(a, goal);
+ }
+}
+static inline void fxmath_decimal_helper_truncate(uint64_t& phi,
+ uint64_t& pmid,
+ uint64_t& plo,
+ uint8_t& scale,
+ uint8_t minscale = 0) {
+ while (scale > minscale) {
+ uint64_t thi = phi, tmid = pmid, tlo = plo;
+ if (fxmath_decimal_helper_div10(thi, tmid, tlo) != 0) {
+ break;
+ }
+ phi = thi, pmid = tmid, plo = tlo;
+ scale--;
+ }
+}
+CFX_Decimal::CFX_Decimal() {
+ m_uLo = m_uMid = m_uHi = m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(uint64_t val) {
+ m_uLo = (uint32_t)val;
+ m_uMid = (uint32_t)FXMATH_DECIMAL_RSHIFT32BIT(val);
+ m_uHi = 0;
+ m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(uint32_t val) {
+ m_uLo = (uint32_t)val;
+ m_uMid = m_uHi = 0;
+ m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(uint32_t lo,
+ uint32_t mid,
+ uint32_t hi,
+ FX_BOOL neg,
+ uint8_t scale) {
+ scale = (scale > FXMATH_DECIMAL_SCALELIMIT ? 0 : scale);
+ m_uLo = lo;
+ m_uMid = mid;
+ m_uHi = hi;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(neg && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(int32_t val) {
+ if (val >= 0) {
+ *this = CFX_Decimal((uint32_t)val);
+ } else {
+ *this = CFX_Decimal((uint32_t)-val);
+ SetNegate();
+ }
+}
+CFX_Decimal::CFX_Decimal(int64_t val) {
+ if (val >= 0) {
+ *this = CFX_Decimal((uint64_t)val);
+ } else {
+ *this = CFX_Decimal((uint64_t)-val);
+ SetNegate();
+ }
+}
+CFX_Decimal::CFX_Decimal(FX_FLOAT val, uint8_t scale) {
+ FX_FLOAT newval = fabs(val);
+ uint64_t phi, pmid, plo;
+ plo = (uint64_t)newval;
+ pmid = (uint64_t)(newval / 1e32);
+ phi = (uint64_t)(newval / 1e64);
+ newval = FXSYS_fmod(newval, 1.0f);
+ for (uint8_t iter = 0; iter < scale; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ newval *= 10;
+ plo += (uint64_t)newval;
+ newval = FXSYS_fmod(newval, 1.0f);
+ }
+ plo += FXSYS_round(newval);
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ m_uHi = (uint32_t)phi;
+ m_uMid = (uint32_t)pmid;
+ m_uLo = (uint32_t)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(val < 0 && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(const CFX_WideStringC& strObj) {
+ const FX_WCHAR* str = strObj.GetPtr();
+ const FX_WCHAR* strBound = str + strObj.GetLength();
+ FX_BOOL pointmet = 0;
+ FX_BOOL negmet = 0;
+ uint8_t scale = 0;
+ m_uHi = m_uMid = m_uLo = 0;
+ while (str != strBound && *str == ' ') {
+ str++;
+ }
+ if (str != strBound && *str == '-') {
+ negmet = 1;
+ str++;
+ } else if (str != strBound && *str == '+') {
+ str++;
+ }
+ while (str != strBound && ((*str >= '0' && *str <= '9') || *str == '.') &&
+ scale < FXMATH_DECIMAL_SCALELIMIT) {
+ if (*str == '.') {
+ if (pointmet) {
+ goto cont;
+ }
+ pointmet = 1;
+ } else {
+ m_uHi = m_uHi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((uint64_t)m_uMid * 0xA);
+ m_uMid = m_uMid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((uint64_t)m_uLo * 0xA);
+ m_uLo = m_uLo * 0xA + (*str - '0');
+ if (pointmet) {
+ scale++;
+ }
+ }
+ cont:
+ str++;
+ }
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(negmet && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(const CFX_ByteStringC& strObj) {
+ CFX_WideString wstrObj;
+ wstrObj.ConvertFrom(strObj);
+ *this = CFX_Decimal(wstrObj);
+}
+CFX_Decimal::operator CFX_WideString() const {
+ CFX_WideString retString;
+ CFX_WideString tmpbuf;
+ uint64_t phi = m_uHi, pmid = m_uMid, plo = m_uLo;
+ while (phi || pmid || plo) {
+ tmpbuf += fxmath_decimal_helper_div10(phi, pmid, plo) + '0';
+ }
+ uint8_t outputlen = (uint8_t)tmpbuf.GetLength();
+ uint8_t scale = (uint8_t)FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ while (scale >= outputlen) {
+ tmpbuf += '0';
+ outputlen++;
+ }
+ if (FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero()) {
+ retString += '-';
+ }
+ for (uint8_t idx = 0; idx < outputlen; idx++) {
+ if (idx == (outputlen - scale) && scale != 0) {
+ retString += '.';
+ }
+ retString += tmpbuf[outputlen - 1 - idx];
+ }
+ return retString;
+}
+CFX_Decimal::operator double() const {
+ double pow = (double)(1 << 16) * (1 << 16);
+ double base =
+ ((double)m_uHi) * pow * pow + ((double)m_uMid) * pow + ((double)m_uLo);
+ int8_t scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ FX_BOOL bNeg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags);
+ return (bNeg ? -1 : 1) * base * ::pow(10.0, -scale);
+}
+void CFX_Decimal::SetScale(uint8_t newscale) {
+ uint8_t oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ if (newscale > oldscale) {
+ uint64_t phi = m_uHi, pmid = m_uMid, plo = m_uLo;
+ for (uint8_t iter = 0; iter < newscale - oldscale; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ }
+ m_uHi = (uint32_t)phi;
+ m_uMid = (uint32_t)pmid;
+ m_uLo = (uint32_t)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
+ FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
+ } else if (newscale < oldscale) {
+ uint64_t phi, pmid, plo;
+ phi = 0, pmid = 0, plo = 5;
+ {
+ for (uint8_t iter = 0; iter < oldscale - newscale - 1; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ }
+ }
+ phi += m_uHi;
+ pmid += m_uMid;
+ plo += m_uLo;
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ {
+ for (uint8_t iter = 0; iter < oldscale - newscale; iter++) {
+ fxmath_decimal_helper_div10(phi, pmid, plo);
+ }
+ }
+ m_uHi = (uint32_t)phi;
+ m_uMid = (uint32_t)pmid;
+ m_uLo = (uint32_t)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
+ FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
+ }
+}
+uint8_t CFX_Decimal::GetScale() {
+ uint8_t oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ return oldscale;
+}
+void CFX_Decimal::SetAbs() {
+ m_uFlags &= ~FXMATH_DECIMAL_NEGMASK;
+}
+void CFX_Decimal::SetNegate() {
+ if (IsNotZero()) {
+ m_uFlags ^= FXMATH_DECIMAL_NEGMASK;
+ }
+}
+void CFX_Decimal::FloorOrCeil(FX_BOOL bFloor) {
+ uint64_t nums[3] = {m_uLo, m_uMid, m_uHi};
+ FX_BOOL bDataLoss = FALSE;
+ for (int i = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); i > 0; i--) {
+ bDataLoss = fxmath_decimal_helper_div10_any(nums, 3) || bDataLoss;
+ }
+ if (bDataLoss && (bFloor ? FXMATH_DECIMAL_FLAGS2NEG(m_uFlags)
+ : !FXMATH_DECIMAL_FLAGS2NEG(m_uFlags))) {
+ fxmath_decimal_helper_inc_any(nums, 3);
+ }
+ m_uHi = (uint32_t)nums[2];
+ m_uMid = (uint32_t)nums[1];
+ m_uLo = (uint32_t)nums[0];
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
+ FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), 0);
+}
+void CFX_Decimal::SetFloor() {
+ FloorOrCeil(TRUE);
+}
+void CFX_Decimal::SetCeiling() {
+ FloorOrCeil(FALSE);
+}
+void CFX_Decimal::SetTruncate() {
+ FloorOrCeil(!FXMATH_DECIMAL_FLAGS2NEG(m_uFlags));
+}
+void CFX_Decimal::Swap(CFX_Decimal& val) {
+ uint32_t tmp;
+ tmp = m_uHi;
+ m_uHi = val.m_uHi;
+ val.m_uHi = tmp;
+ tmp = m_uMid;
+ m_uMid = val.m_uMid;
+ val.m_uMid = tmp;
+ tmp = m_uLo;
+ m_uLo = val.m_uLo;
+ val.m_uLo = tmp;
+ tmp = m_uFlags;
+ m_uFlags = val.m_uFlags;
+ val.m_uFlags = tmp;
+}
+int8_t CFX_Decimal::Compare(const CFX_Decimal& val) const {
+ CFX_Decimal lhs = *this, rhs = val;
+ int8_t retVal = 0;
+ if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) !=
+ FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
+ uint8_t scale = std::min(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags),
+ FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
+ lhs.SetScale(scale);
+ rhs.SetScale(scale);
+ }
+ retVal = -(FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) -
+ FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
+ if (retVal) {
+ return retVal;
+ }
+ retVal = fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo,
+ rhs.m_uHi, rhs.m_uMid, rhs.m_uLo);
+ return (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) ? -retVal : retVal);
+}
+CFX_Decimal CFX_Decimal::AddOrMinus(const CFX_Decimal& val,
+ FX_BOOL isAdding) const {
+ CFX_Decimal lhs = *this, rhs = val;
+ if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) !=
+ FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
+ uint8_t scale = std::max(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags),
+ FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
+ lhs.SetScale(scale);
+ rhs.SetScale(scale);
+ }
+ if (!isAdding) {
+ rhs.SetNegate();
+ }
+ FX_BOOL doRawAdd = (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) ==
+ FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
+ if (doRawAdd) {
+ uint64_t phi = lhs.m_uHi, pmid = lhs.m_uMid, plo = lhs.m_uLo;
+ phi += rhs.m_uHi;
+ pmid += rhs.m_uMid;
+ plo += rhs.m_uLo;
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ if (FXMATH_DECIMAL_RSHIFT32BIT(phi) &&
+ FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != 0) {
+ fxmath_decimal_helper_div10(phi, pmid, plo);
+ lhs.m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(
+ FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags),
+ FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) - 1);
+ }
+ lhs.m_uHi = (uint32_t)phi;
+ lhs.m_uMid = (uint32_t)pmid;
+ lhs.m_uLo = (uint32_t)plo;
+ return lhs;
+ } else {
+ if (fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo,
+ rhs.m_uHi, rhs.m_uMid,
+ rhs.m_uLo) < 0) {
+ lhs.Swap(rhs);
+ }
+ lhs.m_uHi -= rhs.m_uHi;
+ if (lhs.m_uMid < rhs.m_uMid) {
+ lhs.m_uHi--;
+ }
+ lhs.m_uMid -= rhs.m_uMid;
+ if (lhs.m_uLo < rhs.m_uLo) {
+ if (!lhs.m_uMid) {
+ lhs.m_uHi--;
+ }
+ lhs.m_uMid--;
+ }
+ lhs.m_uLo -= rhs.m_uLo;
+ return lhs;
+ }
+}
+CFX_Decimal CFX_Decimal::Multiply(const CFX_Decimal& val) const {
+ uint64_t a[3] = {m_uLo, m_uMid, m_uHi},
+ b[3] = {val.m_uLo, val.m_uMid, val.m_uHi};
+ uint64_t c[6];
+ fxmath_decimal_helper_raw_mul(a, 3, b, 3, c, 6);
+ FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^
+ FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
+ uint8_t scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) +
+ FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
+ fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
+ return CFX_Decimal((uint32_t)c[0], (uint32_t)c[1], (uint32_t)c[2], neg,
+ scale);
+}
+CFX_Decimal CFX_Decimal::Divide(const CFX_Decimal& val) const {
+ if (!val.IsNotZero()) {
+ return CFX_Decimal();
+ }
+ FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^
+ FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
+ uint64_t a[7] = {m_uLo, m_uMid, m_uHi},
+ b[3] = {val.m_uLo, val.m_uMid, val.m_uHi}, c[7] = {0};
+ uint8_t scale = 0;
+ if (FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) <
+ FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags)) {
+ for (int i = FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags) -
+ FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ i > 0; i--) {
+ fxmath_decimal_helper_mul10_any(a, 7);
+ }
+ } else {
+ scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) -
+ FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
+ }
+ uint8_t minscale = scale;
+ if (!IsNotZero()) {
+ return CFX_Decimal(0, 0, 0, 0, minscale);
+ }
+ while (!a[6]) {
+ fxmath_decimal_helper_mul10_any(a, 7);
+ scale++;
+ }
+ fxmath_decimal_helper_div10_any(a, 7);
+ scale--;
+ fxmath_decimal_helper_raw_div(a, 6, b, 3, c, 7);
+ fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
+ fxmath_decimal_helper_truncate(c[2], c[1], c[0], scale, minscale);
+ return CFX_Decimal((uint32_t)c[0], (uint32_t)c[1], (uint32_t)c[2], neg,
+ scale);
+}
+CFX_Decimal CFX_Decimal::Modulus(const CFX_Decimal& val) const {
+ CFX_Decimal lhs = *this, rhs_abs = val;
+ rhs_abs.SetAbs();
+ if (!rhs_abs.IsNotZero()) {
+ return *this;
+ }
+ while (TRUE) {
+ CFX_Decimal lhs_abs = lhs;
+ lhs_abs.SetAbs();
+ if (lhs_abs < rhs_abs) {
+ break;
+ }
+ CFX_Decimal quot = lhs / rhs_abs;
+ quot.SetTruncate();
+ lhs = lhs - quot * rhs_abs;
+ }
+ return lhs;
+}
+FX_BOOL CFX_Decimal::operator==(const CFX_Decimal& val) const {
+ return Compare(val) == 0;
+}
+FX_BOOL CFX_Decimal::operator<=(const CFX_Decimal& val) const {
+ return Compare(val) <= 0;
+}
+FX_BOOL CFX_Decimal::operator>=(const CFX_Decimal& val) const {
+ return Compare(val) >= 0;
+}
+FX_BOOL CFX_Decimal::operator!=(const CFX_Decimal& val) const {
+ return Compare(val) != 0;
+}
+FX_BOOL CFX_Decimal::operator<(const CFX_Decimal& val) const {
+ return Compare(val) < 0;
+}
+FX_BOOL CFX_Decimal::operator>(const CFX_Decimal& val) const {
+ return Compare(val) > 0;
+}
+CFX_Decimal CFX_Decimal::operator+(const CFX_Decimal& val) const {
+ return AddOrMinus(val, TRUE);
+}
+CFX_Decimal CFX_Decimal::operator-(const CFX_Decimal& val) const {
+ return AddOrMinus(val, FALSE);
+}
+CFX_Decimal CFX_Decimal::operator*(const CFX_Decimal& val) const {
+ return Multiply(val);
+}
+CFX_Decimal CFX_Decimal::operator/(const CFX_Decimal& val) const {
+ return Divide(val);
+}
+CFX_Decimal CFX_Decimal::operator%(const CFX_Decimal& val) const {
+ return Modulus(val);
+}
diff --git a/xfa/src/fgas/src/localization/fx_localeimp.h b/xfa/src/fgas/src/localization/fx_localeimp.h
index 2ebbaa867d..1de517f8b6 100644
--- a/xfa/src/fgas/src/localization/fx_localeimp.h
+++ b/xfa/src/fgas/src/localization/fx_localeimp.h
@@ -1,116 +1,116 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_LOCALE_IMP_H_
-#define _FX_LOCALE_IMP_H_
-class CFX_LCNumeric;
-class CFX_Locale : public IFX_Locale {
- public:
- CFX_Locale(CXML_Element* pLocaleData);
- virtual void Release() { delete this; }
-
- virtual CFX_WideString GetName();
- virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
- CFX_WideString& wsNumSymbol) const;
-
- virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
- virtual void GetMonthName(int32_t nMonth,
- CFX_WideString& wsMonthName,
- FX_BOOL bAbbr = TRUE) const;
- virtual void GetDayName(int32_t nWeek,
- CFX_WideString& wsDayName,
- FX_BOOL bAbbr = TRUE) const;
- virtual void GetMeridiemName(CFX_WideString& wsMeridiemName,
- FX_BOOL bAM = TRUE) const;
- virtual void GetTimeZone(FX_TIMEZONE& tz) const;
- virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
-
- virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
- CFX_WideString& wsPattern) const;
- virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
- CFX_WideString& wsPattern) const;
- virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
- CFX_WideString& wsPattern) const;
-
- protected:
- virtual ~CFX_Locale();
- CXML_Element* m_pElement;
-};
-class CFX_FormatString : public IFX_FormatString {
- public:
- CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID);
- virtual void Release() { delete this; }
-
- virtual void SplitFormatString(const CFX_WideString& wsFormatString,
- CFX_WideStringArray& wsPatterns);
- virtual FX_LOCALECATEGORY GetCategory(const CFX_WideString& wsPattern);
- virtual FX_WORD GetLCID(const CFX_WideString& wsPattern);
- virtual CFX_WideString GetLocaleName(const CFX_WideString& wsPattern);
- virtual FX_BOOL ParseText(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsValue);
- virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- FX_FLOAT& fValue);
- virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsValue);
- virtual FX_BOOL ParseDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- FX_DATETIMETYPE eDateTimeType,
- CFX_Unitime& dtValue);
- virtual FX_BOOL ParseZero(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern);
- virtual FX_BOOL ParseNull(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern);
- virtual FX_BOOL FormatText(const CFX_WideString& wsSrcText,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatNum(const CFX_WideString& wsSrcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatNum(FX_FLOAT fNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput,
- FX_DATETIMETYPE eDateTimeType);
- virtual FX_BOOL FormatDateTime(const CFX_Unitime& dt,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatZero(const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- virtual FX_BOOL FormatNull(const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
-
- protected:
- virtual ~CFX_FormatString();
- IFX_Locale* GetTextFormat(const CFX_WideString& wsPattern,
- const CFX_WideStringC& wsCategory,
- CFX_WideString& wsPurgePattern);
- IFX_Locale* GetNumericFormat(const CFX_WideString& wsPattern,
- int32_t& iDotIndex,
- FX_DWORD& dwStyle,
- CFX_WideString& wsPurgePattern);
- FX_BOOL FormatStrNum(const CFX_WideStringC& wsInputNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- FX_BOOL FormatLCNumeric(CFX_LCNumeric& lcNum,
- const CFX_WideString& wsPattern,
- CFX_WideString& wsOutput);
- FX_DATETIMETYPE GetDateTimeFormat(const CFX_WideString& wsPattern,
- IFX_Locale*& pLocale,
- CFX_WideString& wsDatePattern,
- CFX_WideString& wsTimePattern);
- IFX_Locale* GetPatternLocale(const CFX_WideStringC& wsLocale);
- IFX_LocaleMgr* m_pLocaleMgr;
- FX_BOOL m_bUseLCID;
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LOCALE_IMP_H_
+#define _FX_LOCALE_IMP_H_
+class CFX_LCNumeric;
+class CFX_Locale : public IFX_Locale {
+ public:
+ CFX_Locale(CXML_Element* pLocaleData);
+ virtual void Release() { delete this; }
+
+ virtual CFX_WideString GetName();
+ virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+ CFX_WideString& wsNumSymbol) const;
+
+ virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+ virtual void GetMonthName(int32_t nMonth,
+ CFX_WideString& wsMonthName,
+ FX_BOOL bAbbr = TRUE) const;
+ virtual void GetDayName(int32_t nWeek,
+ CFX_WideString& wsDayName,
+ FX_BOOL bAbbr = TRUE) const;
+ virtual void GetMeridiemName(CFX_WideString& wsMeridiemName,
+ FX_BOOL bAM = TRUE) const;
+ virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+ virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+ virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+ CFX_WideString& wsPattern) const;
+ virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+ CFX_WideString& wsPattern) const;
+ virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+ CFX_WideString& wsPattern) const;
+
+ protected:
+ virtual ~CFX_Locale();
+ CXML_Element* m_pElement;
+};
+class CFX_FormatString : public IFX_FormatString {
+ public:
+ CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID);
+ virtual void Release() { delete this; }
+
+ virtual void SplitFormatString(const CFX_WideString& wsFormatString,
+ CFX_WideStringArray& wsPatterns);
+ virtual FX_LOCALECATEGORY GetCategory(const CFX_WideString& wsPattern);
+ virtual FX_WORD GetLCID(const CFX_WideString& wsPattern);
+ virtual CFX_WideString GetLocaleName(const CFX_WideString& wsPattern);
+ virtual FX_BOOL ParseText(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsValue);
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ FX_FLOAT& fValue);
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsValue);
+ virtual FX_BOOL ParseDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ FX_DATETIMETYPE eDateTimeType,
+ CFX_Unitime& dtValue);
+ virtual FX_BOOL ParseZero(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern);
+ virtual FX_BOOL ParseNull(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern);
+ virtual FX_BOOL FormatText(const CFX_WideString& wsSrcText,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNum(const CFX_WideString& wsSrcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNum(FX_FLOAT fNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput,
+ FX_DATETIMETYPE eDateTimeType);
+ virtual FX_BOOL FormatDateTime(const CFX_Unitime& dt,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatZero(const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNull(const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+
+ protected:
+ virtual ~CFX_FormatString();
+ IFX_Locale* GetTextFormat(const CFX_WideString& wsPattern,
+ const CFX_WideStringC& wsCategory,
+ CFX_WideString& wsPurgePattern);
+ IFX_Locale* GetNumericFormat(const CFX_WideString& wsPattern,
+ int32_t& iDotIndex,
+ FX_DWORD& dwStyle,
+ CFX_WideString& wsPurgePattern);
+ FX_BOOL FormatStrNum(const CFX_WideStringC& wsInputNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ FX_BOOL FormatLCNumeric(CFX_LCNumeric& lcNum,
+ const CFX_WideString& wsPattern,
+ CFX_WideString& wsOutput);
+ FX_DATETIMETYPE GetDateTimeFormat(const CFX_WideString& wsPattern,
+ IFX_Locale*& pLocale,
+ CFX_WideString& wsDatePattern,
+ CFX_WideString& wsTimePattern);
+ IFX_Locale* GetPatternLocale(const CFX_WideStringC& wsLocale);
+ IFX_LocaleMgr* m_pLocaleMgr;
+ FX_BOOL m_bUseLCID;
+};
+#endif
diff --git a/xfa/src/fgas/src/localization/fx_localemgr.cpp b/xfa/src/fgas/src/localization/fx_localemgr.cpp
index cea681bf56..b7362633c6 100644
--- a/xfa/src/fgas/src/localization/fx_localemgr.cpp
+++ b/xfa/src/fgas/src/localization/fx_localemgr.cpp
@@ -1,97 +1,97 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/include/fxcrt/fx_xml.h"
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_localemgr.h"
-
-IFX_LocaleMgr* FX_LocaleMgr_Create(const FX_WCHAR* pszLocalPath,
- FX_WORD wDefaultLCID) {
- void* pPathHandle = FX_OpenFolder(pszLocalPath);
- if (!pPathHandle) {
- return NULL;
- }
- CFX_LocaleMgr* pLocaleMgr = new CFX_LocaleMgr(wDefaultLCID);
- CFX_WideString wsFileName;
- FX_BOOL bFolder = FALSE;
- while (FX_GetNextFile(pPathHandle, wsFileName, bFolder)) {
- if (!bFolder) {
- if (wsFileName.GetLength() < 4) {
- continue;
- }
- CFX_WideString wsExt = wsFileName.Right(4);
- wsExt.MakeLower();
- if (wsExt != L".xml") {
- continue;
- }
- CFX_WideString wsFullPath(pszLocalPath);
- wsFullPath += L"\\" + wsFileName;
- IFX_FileRead* pRead = FX_CreateFileRead(wsFullPath);
- if (!pRead) {
- continue;
- }
- CXML_Element* pXmlLocale = CXML_Element::Parse(pRead);
- pRead->Release();
- CFX_ByteString bssp = pXmlLocale->GetNamespace();
- if (bssp == "http://www.foxitsoftware.com/localization") {
- CFX_WideString wsLCID = pXmlLocale->GetAttrValue("", "lcid");
- wchar_t* pEnd = NULL;
- FX_DWORD dwLCID = wcstol(wsLCID, &pEnd, 16);
- if (pLocaleMgr->m_lcid2xml.GetValueAt((void*)(uintptr_t)dwLCID)) {
- delete pXmlLocale;
- } else {
- pLocaleMgr->m_lcid2xml.SetAt((void*)(uintptr_t)dwLCID, pXmlLocale);
- }
- } else {
- delete pXmlLocale;
- }
- }
- }
- FX_CloseFolder(pPathHandle);
- return pLocaleMgr;
-}
-CFX_LocaleMgr::CFX_LocaleMgr(FX_WORD wDefLCID) : m_wDefLCID(wDefLCID) {}
-CFX_LocaleMgr::~CFX_LocaleMgr() {
- FX_POSITION ps = m_lcid2locale.GetStartPosition();
- while (ps) {
- void* plcid;
- IFX_Locale* pLocale = NULL;
- m_lcid2locale.GetNextAssoc(ps, plcid, (void*&)pLocale);
- pLocale->Release();
- }
- m_lcid2locale.RemoveAll();
- ps = m_lcid2xml.GetStartPosition();
- while (ps) {
- void* plcid;
- CXML_Element* pxml = NULL;
- m_lcid2xml.GetNextAssoc(ps, plcid, (void*&)pxml);
- delete pxml;
- }
- m_lcid2xml.RemoveAll();
-}
-FX_WORD CFX_LocaleMgr::GetDefLocaleID() {
- return m_wDefLCID;
-}
-IFX_Locale* CFX_LocaleMgr::GetDefLocale() {
- return GetLocale(m_wDefLCID);
-}
-IFX_Locale* CFX_LocaleMgr::GetLocale(FX_WORD lcid) {
- IFX_Locale* pLocale =
- (IFX_Locale*)m_lcid2locale.GetValueAt((void*)(uintptr_t)lcid);
- if (!pLocale) {
- CXML_Element* pxml =
- (CXML_Element*)m_lcid2xml.GetValueAt((void*)(uintptr_t)lcid);
- if (pxml) {
- pLocale = IFX_Locale::Create(pxml);
- m_lcid2locale.SetAt((void*)(uintptr_t)lcid, pLocale);
- }
- }
- return pLocale;
-}
-IFX_Locale* CFX_LocaleMgr::GetLocaleByName(
- const CFX_WideStringC& wsLocaleName) {
- return NULL;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/include/fxcrt/fx_xml.h"
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_localemgr.h"
+
+IFX_LocaleMgr* FX_LocaleMgr_Create(const FX_WCHAR* pszLocalPath,
+ FX_WORD wDefaultLCID) {
+ void* pPathHandle = FX_OpenFolder(pszLocalPath);
+ if (!pPathHandle) {
+ return NULL;
+ }
+ CFX_LocaleMgr* pLocaleMgr = new CFX_LocaleMgr(wDefaultLCID);
+ CFX_WideString wsFileName;
+ FX_BOOL bFolder = FALSE;
+ while (FX_GetNextFile(pPathHandle, wsFileName, bFolder)) {
+ if (!bFolder) {
+ if (wsFileName.GetLength() < 4) {
+ continue;
+ }
+ CFX_WideString wsExt = wsFileName.Right(4);
+ wsExt.MakeLower();
+ if (wsExt != L".xml") {
+ continue;
+ }
+ CFX_WideString wsFullPath(pszLocalPath);
+ wsFullPath += L"\\" + wsFileName;
+ IFX_FileRead* pRead = FX_CreateFileRead(wsFullPath);
+ if (!pRead) {
+ continue;
+ }
+ CXML_Element* pXmlLocale = CXML_Element::Parse(pRead);
+ pRead->Release();
+ CFX_ByteString bssp = pXmlLocale->GetNamespace();
+ if (bssp == "http://www.foxitsoftware.com/localization") {
+ CFX_WideString wsLCID = pXmlLocale->GetAttrValue("", "lcid");
+ wchar_t* pEnd = NULL;
+ FX_DWORD dwLCID = wcstol(wsLCID, &pEnd, 16);
+ if (pLocaleMgr->m_lcid2xml.GetValueAt((void*)(uintptr_t)dwLCID)) {
+ delete pXmlLocale;
+ } else {
+ pLocaleMgr->m_lcid2xml.SetAt((void*)(uintptr_t)dwLCID, pXmlLocale);
+ }
+ } else {
+ delete pXmlLocale;
+ }
+ }
+ }
+ FX_CloseFolder(pPathHandle);
+ return pLocaleMgr;
+}
+CFX_LocaleMgr::CFX_LocaleMgr(FX_WORD wDefLCID) : m_wDefLCID(wDefLCID) {}
+CFX_LocaleMgr::~CFX_LocaleMgr() {
+ FX_POSITION ps = m_lcid2locale.GetStartPosition();
+ while (ps) {
+ void* plcid;
+ IFX_Locale* pLocale = NULL;
+ m_lcid2locale.GetNextAssoc(ps, plcid, (void*&)pLocale);
+ pLocale->Release();
+ }
+ m_lcid2locale.RemoveAll();
+ ps = m_lcid2xml.GetStartPosition();
+ while (ps) {
+ void* plcid;
+ CXML_Element* pxml = NULL;
+ m_lcid2xml.GetNextAssoc(ps, plcid, (void*&)pxml);
+ delete pxml;
+ }
+ m_lcid2xml.RemoveAll();
+}
+FX_WORD CFX_LocaleMgr::GetDefLocaleID() {
+ return m_wDefLCID;
+}
+IFX_Locale* CFX_LocaleMgr::GetDefLocale() {
+ return GetLocale(m_wDefLCID);
+}
+IFX_Locale* CFX_LocaleMgr::GetLocale(FX_WORD lcid) {
+ IFX_Locale* pLocale =
+ (IFX_Locale*)m_lcid2locale.GetValueAt((void*)(uintptr_t)lcid);
+ if (!pLocale) {
+ CXML_Element* pxml =
+ (CXML_Element*)m_lcid2xml.GetValueAt((void*)(uintptr_t)lcid);
+ if (pxml) {
+ pLocale = IFX_Locale::Create(pxml);
+ m_lcid2locale.SetAt((void*)(uintptr_t)lcid, pLocale);
+ }
+ }
+ return pLocale;
+}
+IFX_Locale* CFX_LocaleMgr::GetLocaleByName(
+ const CFX_WideStringC& wsLocaleName) {
+ return NULL;
+}
diff --git a/xfa/src/fgas/src/localization/fx_localemgr.h b/xfa/src/fgas/src/localization/fx_localemgr.h
index ca3e90ec58..1428a4346a 100644
--- a/xfa/src/fgas/src/localization/fx_localemgr.h
+++ b/xfa/src/fgas/src/localization/fx_localemgr.h
@@ -1,24 +1,24 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_LOCALEMGR_IMP_H_
-#define _FX_LOCALEMGR_IMP_H_
-class CFX_LocaleMgr : public IFX_LocaleMgr {
- public:
- CFX_LocaleMgr(FX_WORD wDefLCID);
- virtual void Release() { delete this; }
- virtual FX_WORD GetDefLocaleID();
- virtual IFX_Locale* GetDefLocale();
- virtual IFX_Locale* GetLocale(FX_WORD lcid);
- virtual IFX_Locale* GetLocaleByName(const CFX_WideStringC& wsLocaleName);
- CFX_MapPtrToPtr m_lcid2xml;
-
- protected:
- ~CFX_LocaleMgr();
- CFX_MapPtrToPtr m_lcid2locale;
- FX_WORD m_wDefLCID;
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LOCALEMGR_IMP_H_
+#define _FX_LOCALEMGR_IMP_H_
+class CFX_LocaleMgr : public IFX_LocaleMgr {
+ public:
+ CFX_LocaleMgr(FX_WORD wDefLCID);
+ virtual void Release() { delete this; }
+ virtual FX_WORD GetDefLocaleID();
+ virtual IFX_Locale* GetDefLocale();
+ virtual IFX_Locale* GetLocale(FX_WORD lcid);
+ virtual IFX_Locale* GetLocaleByName(const CFX_WideStringC& wsLocaleName);
+ CFX_MapPtrToPtr m_lcid2xml;
+
+ protected:
+ ~CFX_LocaleMgr();
+ CFX_MapPtrToPtr m_lcid2locale;
+ FX_WORD m_wDefLCID;
+};
+#endif
diff --git a/xfa/src/fgas/src/xml/fx_sax_imp.cpp b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
index 6b3cc778ab..bb1602ca72 100644
--- a/xfa/src/fgas/src/xml/fx_sax_imp.cpp
+++ b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
@@ -1,689 +1,689 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include <algorithm>
-
-#include "xfa/src/fgas/src/fgas_base.h"
-#include "fx_sax_imp.h"
-
-namespace {
-
-const FX_DWORD kSaxFileBufSize = 32768;
-
-} // namespace
-
-IFX_SAXReader* FX_SAXReader_Create() {
- return new CFX_SAXReader;
-}
-CFX_SAXFile::CFX_SAXFile()
- : m_pFile(NULL),
- m_dwStart(0),
- m_dwEnd(0),
- m_dwCur(0),
- m_pBuf(NULL),
- m_dwBufSize(0),
- m_dwBufIndex(0) {}
-FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead* pFile,
- FX_DWORD dwStart,
- FX_DWORD dwLen) {
- FXSYS_assert(m_pFile == NULL && pFile != NULL);
- FX_DWORD dwSize = pFile->GetSize();
- if (dwStart >= dwSize) {
- return FALSE;
- }
- if (dwLen == -1 || dwStart + dwLen > dwSize) {
- dwLen = dwSize - dwStart;
- }
- if (dwLen == 0) {
- return FALSE;
- }
- m_dwBufSize = std::min(dwLen, kSaxFileBufSize);
- m_pBuf = FX_Alloc(uint8_t, m_dwBufSize);
- if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
- return FALSE;
- }
- m_dwStart = dwStart;
- m_dwEnd = dwStart + dwLen;
- m_dwCur = dwStart;
- m_pFile = pFile;
- m_dwBufIndex = 0;
- return TRUE;
-}
-FX_BOOL CFX_SAXFile::ReadNextBlock() {
- FXSYS_assert(m_pFile != NULL);
- FX_DWORD dwSize = m_dwEnd - m_dwCur;
- if (dwSize == 0) {
- return FALSE;
- }
- m_dwBufSize = std::min(dwSize, kSaxFileBufSize);
- if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) {
- return FALSE;
- }
- m_dwBufIndex = 0;
- return TRUE;
-}
-void CFX_SAXFile::Reset() {
- if (m_pBuf) {
- FX_Free(m_pBuf);
- m_pBuf = NULL;
- }
- m_pFile = NULL;
-}
-CFX_SAXReader::CFX_SAXReader()
- : m_File(),
- m_pHandler(nullptr),
- m_iState(-1),
- m_pRoot(nullptr),
- m_pCurItem(nullptr),
- m_dwItemID(0),
- m_iDataSize(256),
- m_iNameSize(256),
- m_dwParseMode(0),
- m_pCommentContext(nullptr) {
- m_pszData = FX_Alloc(uint8_t, m_iDataSize);
- m_pszName = FX_Alloc(uint8_t, m_iNameSize);
-}
-CFX_SAXReader::~CFX_SAXReader() {
- Reset();
- if (m_pszData) {
- FX_Free(m_pszData);
- m_pszData = NULL;
- }
- if (m_pszName) {
- FX_Free(m_pszName);
- m_pszName = NULL;
- }
-}
-void CFX_SAXReader::Reset() {
- m_File.Reset();
- CFX_SAXItem* pItem = m_pRoot;
- while (pItem) {
- CFX_SAXItem* pNext = pItem->m_pNext;
- delete pItem;
- pItem = pNext;
- }
- m_pRoot = NULL;
- m_pCurItem = NULL;
- m_dwItemID = 0;
- m_SkipStack.RemoveAll();
- m_SkipChar = 0;
- m_iDataLength = 0;
- m_iEntityStart = -1;
- m_iNameLength = 0;
- m_iDataPos = 0;
- if (m_pCommentContext) {
- delete m_pCommentContext;
- m_pCommentContext = NULL;
- }
-}
-inline void CFX_SAXReader::Push() {
- CFX_SAXItem* pNew = new CFX_SAXItem;
- pNew->m_dwID = ++m_dwItemID;
- pNew->m_bSkip = m_pCurItem->m_bSkip;
- pNew->m_pPrev = m_pCurItem;
- m_pCurItem->m_pNext = pNew;
- m_pCurItem = pNew;
-}
-inline void CFX_SAXReader::Pop() {
- if (!m_pCurItem) {
- return;
- }
- CFX_SAXItem* pPrev = m_pCurItem->m_pPrev;
- pPrev->m_pNext = NULL;
- delete m_pCurItem;
- m_pCurItem = pPrev;
-}
-inline void CFX_SAXReader::AppendData(uint8_t ch) {
- ReallocDataBuffer();
- m_pszData[m_iDataPos++] = ch;
-}
-inline void CFX_SAXReader::AppendName(uint8_t ch) {
- ReallocNameBuffer();
- m_pszName[m_iDataPos++] = ch;
-}
-void CFX_SAXReader::ReallocDataBuffer() {
- if (m_iDataPos < m_iDataSize) {
- return;
- }
- if (m_iDataSize <= 1024 * 1024) {
- m_iDataSize *= 2;
- } else {
- m_iDataSize += 1024 * 1024;
- }
- m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize);
-}
-void CFX_SAXReader::ReallocNameBuffer() {
- if (m_iDataPos < m_iNameSize) {
- return;
- }
- if (m_iNameSize <= 1024 * 1024) {
- m_iNameSize *= 2;
- } else {
- m_iNameSize += 1024 * 1024;
- }
- m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize);
-}
-inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) {
- return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21;
-}
-int32_t CFX_SAXReader::StartParse(IFX_FileRead* pFile,
- FX_DWORD dwStart,
- FX_DWORD dwLen,
- FX_DWORD dwParseMode) {
- m_iState = -1;
- Reset();
- if (!m_File.StartFile(pFile, dwStart, dwLen)) {
- return -1;
- }
- m_iState = 0;
- m_eMode = FX_SAXMODE_Text;
- m_ePrevMode = FX_SAXMODE_Text;
- m_bCharData = FALSE;
- m_dwDataOffset = 0;
- m_pRoot = m_pCurItem = new CFX_SAXItem;
- m_pCurItem->m_dwID = ++m_dwItemID;
- m_dwParseMode = dwParseMode;
- return 0;
-}
-typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)();
-static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = {
- &CFX_SAXReader::ParseText,
- &CFX_SAXReader::ParseNodeStart,
- &CFX_SAXReader::ParseDeclOrComment,
- &CFX_SAXReader::ParseDeclNode,
- &CFX_SAXReader::ParseComment,
- &CFX_SAXReader::ParseCommentContent,
- &CFX_SAXReader::ParseTagName,
- &CFX_SAXReader::ParseTagAttributeName,
- &CFX_SAXReader::ParseTagAttributeEqual,
- &CFX_SAXReader::ParseTagAttributeValue,
- &CFX_SAXReader::ParseMaybeClose,
- &CFX_SAXReader::ParseTagClose,
- &CFX_SAXReader::ParseTagEnd,
- &CFX_SAXReader::ParseTargetData,
-};
-int32_t CFX_SAXReader::ContinueParse(IFX_Pause* pPause) {
- if (m_iState < 0 || m_iState > 99) {
- return m_iState;
- }
- while (m_File.m_dwCur < m_File.m_dwEnd) {
- FX_DWORD& index = m_File.m_dwBufIndex;
- FX_DWORD size = m_File.m_dwBufSize;
- const uint8_t* pBuf = m_File.m_pBuf;
- while (index < size) {
- m_CurByte = pBuf[index];
- (this->*g_FX_SAXReader_LPFParse[m_eMode])();
- index++;
- }
- m_File.m_dwCur += index;
- m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 /
- (m_File.m_dwEnd - m_File.m_dwStart);
- if (m_File.m_dwCur >= m_File.m_dwEnd) {
- break;
- }
- if (!m_File.ReadNextBlock()) {
- m_iState = -2;
- break;
- }
- m_dwDataOffset = 0;
- if (pPause && pPause->NeedToPauseNow()) {
- break;
- }
- }
- return m_iState;
-}
-void CFX_SAXReader::ParseChar(uint8_t ch) {
- ReallocDataBuffer();
- m_pszData[m_iDataPos] = ch;
- if (m_iEntityStart > -1 && ch == ';') {
- int32_t iSaveEntityStart = m_iEntityStart;
- CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1,
- m_iDataPos - m_iEntityStart - 1);
- int32_t iLen = csEntity.GetLength();
- if (iLen > 0) {
- if (csEntity[0] == '#') {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) {
- ch = 0;
- uint8_t w;
- if (iLen > 1 && csEntity[1] == 'x') {
- for (int32_t i = 2; i < iLen; i++) {
- w = csEntity[i];
- if (w >= '0' && w <= '9') {
- ch = (ch << 4) + w - '0';
- } else if (w >= 'A' && w <= 'F') {
- ch = (ch << 4) + w - 55;
- } else if (w >= 'a' && w <= 'f') {
- ch = (ch << 4) + w - 87;
- } else {
- break;
- }
- }
- } else {
- for (int32_t i = 1; i < iLen; i++) {
- w = csEntity[i];
- if (w < '0' || w > '9') {
- break;
- }
- ch = ch * 10 + w - '0';
- }
- }
- if (ch != 0) {
- m_pszData[m_iEntityStart++] = ch;
- }
- }
- } else {
- if (csEntity.Compare("amp") == 0) {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) {
- m_pszData[m_iEntityStart++] = '&';
- }
- } else if (csEntity.Compare("lt") == 0) {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) {
- m_pszData[m_iEntityStart++] = '<';
- }
- } else if (csEntity.Compare("gt") == 0) {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) {
- m_pszData[m_iEntityStart++] = '>';
- }
- } else if (csEntity.Compare("apos") == 0) {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) {
- m_pszData[m_iEntityStart++] = '\'';
- }
- } else if (csEntity.Compare("quot") == 0) {
- if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) {
- m_pszData[m_iEntityStart++] = '\"';
- }
- }
- }
- }
- if (iSaveEntityStart != m_iEntityStart) {
- m_iDataPos = m_iEntityStart;
- m_iEntityStart = -1;
- } else {
- m_iDataPos++;
- m_iEntityStart = -1;
- }
- } else {
- if (m_iEntityStart < 0 && ch == '&') {
- m_iEntityStart = m_iDataPos;
- }
- m_iDataPos++;
- }
-}
-void CFX_SAXReader::ParseText() {
- if (m_CurByte == '<') {
- if (m_iDataPos > 0) {
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyData();
- }
- }
- Push();
- m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
- m_eMode = FX_SAXMODE_NodeStart;
- return;
- }
- if (m_iDataPos < 1 && SkipSpace(m_CurByte)) {
- return;
- }
- ParseChar(m_CurByte);
-}
-void CFX_SAXReader::ParseNodeStart() {
- if (m_CurByte == '?') {
- m_pCurItem->m_eNode = FX_SAXNODE_Instruction;
- m_eMode = FX_SAXMODE_TagName;
- return;
- }
- if (m_CurByte == '!') {
- m_eMode = FX_SAXMODE_DeclOrComment;
- return;
- }
- if (m_CurByte == '/') {
- m_eMode = FX_SAXMODE_TagEnd;
- return;
- }
- if (m_CurByte == '>') {
- Pop();
- m_eMode = FX_SAXMODE_Text;
- return;
- }
- if (m_CurByte > 0x20) {
- m_dwDataOffset = m_File.m_dwBufIndex;
- m_pCurItem->m_eNode = FX_SAXNODE_Tag;
- m_eMode = FX_SAXMODE_TagName;
- AppendData(m_CurByte);
- }
-}
-void CFX_SAXReader::ParseDeclOrComment() {
- if (m_CurByte == '-') {
- m_eMode = FX_SAXMODE_Comment;
- m_pCurItem->m_eNode = FX_SAXNODE_Comment;
- if (m_pCommentContext == NULL) {
- m_pCommentContext = new CFX_SAXCommentContext;
- }
- m_pCommentContext->m_iHeaderCount = 1;
- m_pCommentContext->m_iTailCount = 0;
- } else {
- m_eMode = FX_SAXMODE_DeclNode;
- m_dwDataOffset = m_File.m_dwBufIndex;
- m_SkipChar = '>';
- m_SkipStack.Add('>');
- SkipNode();
- }
-}
-void CFX_SAXReader::ParseComment() {
- m_pCommentContext->m_iHeaderCount = 2;
- m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
- m_eMode = FX_SAXMODE_CommentContent;
-}
-void CFX_SAXReader::ParseCommentContent() {
- if (m_CurByte == '-') {
- m_pCommentContext->m_iTailCount++;
- } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) {
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyTargetData();
- }
- Pop();
- m_eMode = FX_SAXMODE_Text;
- } else {
- while (m_pCommentContext->m_iTailCount > 0) {
- AppendData('-');
- m_pCommentContext->m_iTailCount--;
- }
- AppendData(m_CurByte);
- }
-}
-void CFX_SAXReader::ParseDeclNode() {
- SkipNode();
-}
-void CFX_SAXReader::ParseTagName() {
- if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' ||
- m_CurByte == '?') {
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyEnter();
- }
- if (m_CurByte < 0x21) {
- m_eMode = FX_SAXMODE_TagAttributeName;
- } else if (m_CurByte == '/' || m_CurByte == '?') {
- m_ePrevMode = m_eMode;
- m_eMode = FX_SAXMODE_TagMaybeClose;
- } else {
- if (m_pHandler) {
- NotifyBreak();
- }
- m_eMode = FX_SAXMODE_Text;
- }
- } else {
- AppendData(m_CurByte);
- }
-}
-void CFX_SAXReader::ParseTagAttributeName() {
- if (m_CurByte < 0x21 || m_CurByte == '=') {
- if (m_iDataPos < 1 && m_CurByte < 0x21) {
- return;
- }
- m_iNameLength = m_iDataPos;
- m_iDataPos = 0;
- m_SkipChar = 0;
- m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue
- : FX_SAXMODE_TagAttributeEqual;
- return;
- }
- if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
- if (m_CurByte == '/' || m_CurByte == '?') {
- m_ePrevMode = m_eMode;
- m_eMode = FX_SAXMODE_TagMaybeClose;
- } else {
- if (m_pHandler) {
- NotifyBreak();
- }
- m_eMode = FX_SAXMODE_Text;
- }
- return;
- }
- if (m_iDataPos < 1) {
- m_dwDataOffset = m_File.m_dwBufIndex;
- }
- AppendName(m_CurByte);
-}
-void CFX_SAXReader::ParseTagAttributeEqual() {
- if (m_CurByte == '=') {
- m_SkipChar = 0;
- m_eMode = FX_SAXMODE_TagAttributeValue;
- return;
- } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_iDataPos = m_iNameLength;
- AppendName(0x20);
- m_eMode = FX_SAXMODE_TargetData;
- ParseTargetData();
- }
-}
-void CFX_SAXReader::ParseTagAttributeValue() {
- if (m_SkipChar) {
- if (m_SkipChar == m_CurByte) {
- {
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyAttribute();
- }
- }
- m_SkipChar = 0;
- m_eMode = FX_SAXMODE_TagAttributeName;
- return;
- }
- ParseChar(m_CurByte);
- return;
- }
- if (m_CurByte < 0x21) {
- return;
- }
- if (m_iDataPos < 1) {
- if (m_CurByte == '\'' || m_CurByte == '\"') {
- m_SkipChar = m_CurByte;
- }
- }
-}
-void CFX_SAXReader::ParseMaybeClose() {
- if (m_CurByte == '>') {
- if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_iNameLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyTargetData();
- }
- }
- ParseTagClose();
- m_eMode = FX_SAXMODE_Text;
- } else if (m_ePrevMode == FX_SAXMODE_TagName) {
- AppendData('/');
- m_eMode = FX_SAXMODE_TagName;
- m_ePrevMode = FX_SAXMODE_Text;
- ParseTagName();
- } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) {
- AppendName('/');
- m_eMode = FX_SAXMODE_TagAttributeName;
- m_ePrevMode = FX_SAXMODE_Text;
- ParseTagAttributeName();
- } else if (m_ePrevMode == FX_SAXMODE_TargetData) {
- AppendName('?');
- m_eMode = FX_SAXMODE_TargetData;
- m_ePrevMode = FX_SAXMODE_Text;
- ParseTargetData();
- }
-}
-void CFX_SAXReader::ParseTagClose() {
- m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
- if (m_pHandler) {
- NotifyClose();
- }
- Pop();
-}
-void CFX_SAXReader::ParseTagEnd() {
- if (m_CurByte < 0x21) {
- return;
- }
- if (m_CurByte == '>') {
- Pop();
- m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_pHandler) {
- NotifyEnd();
- }
- Pop();
- m_eMode = FX_SAXMODE_Text;
- } else {
- ParseChar(m_CurByte);
- }
-}
-void CFX_SAXReader::ParseTargetData() {
- if (m_CurByte == '?') {
- m_ePrevMode = m_eMode;
- m_eMode = FX_SAXMODE_TagMaybeClose;
- } else {
- AppendName(m_CurByte);
- }
-}
-void CFX_SAXReader::SkipNode() {
- int32_t iLen = m_SkipStack.GetSize();
- if (m_SkipChar == '\'' || m_SkipChar == '\"') {
- if (m_CurByte != m_SkipChar) {
- return;
- }
- iLen--;
- FXSYS_assert(iLen > -1);
- m_SkipStack.RemoveAt(iLen, 1);
- m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
- return;
- }
- switch (m_CurByte) {
- case '<':
- m_SkipChar = '>';
- m_SkipStack.Add('>');
- break;
- case '[':
- m_SkipChar = ']';
- m_SkipStack.Add(']');
- break;
- case '(':
- m_SkipChar = ')';
- m_SkipStack.Add(')');
- break;
- case '\'':
- m_SkipChar = '\'';
- m_SkipStack.Add('\'');
- break;
- case '\"':
- m_SkipChar = '\"';
- m_SkipStack.Add('\"');
- break;
- default:
- if (m_CurByte == m_SkipChar) {
- iLen--;
- m_SkipStack.RemoveAt(iLen, 1);
- m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
- if (iLen == 0 && m_CurByte == '>') {
- m_iDataLength = m_iDataPos;
- m_iDataPos = 0;
- if (m_iDataLength >= 9 &&
- FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 &&
- FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]",
- 2 * sizeof(uint8_t)) == 0) {
- Pop();
- m_iDataLength -= 9;
- m_dwDataOffset += 7;
- FXSYS_memmove(m_pszData, m_pszData + 7,
- m_iDataLength * sizeof(uint8_t));
- m_bCharData = TRUE;
- if (m_pHandler) {
- NotifyData();
- }
- m_bCharData = FALSE;
- } else {
- Pop();
- }
- m_eMode = FX_SAXMODE_Text;
- }
- }
- break;
- }
- if (iLen > 0) {
- ParseChar(m_CurByte);
- }
-}
-void CFX_SAXReader::NotifyData() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag)
- m_pHandler->OnTagData(m_pCurItem->m_pNode,
- m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text,
- CFX_ByteStringC(m_pszData, m_iDataLength),
- m_File.m_dwCur + m_dwDataOffset);
-}
-void CFX_SAXReader::NotifyEnter() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
- m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_pCurItem->m_pNode =
- m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength),
- m_pCurItem->m_eNode, m_dwNodePos);
- }
-}
-void CFX_SAXReader::NotifyAttribute() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
- m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_pHandler->OnTagAttribute(m_pCurItem->m_pNode,
- CFX_ByteStringC(m_pszName, m_iNameLength),
- CFX_ByteStringC(m_pszData, m_iDataLength));
- }
-}
-void CFX_SAXReader::NotifyBreak() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
- m_pHandler->OnTagBreak(m_pCurItem->m_pNode);
- }
-}
-void CFX_SAXReader::NotifyClose() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
- m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos);
- }
-}
-void CFX_SAXReader::NotifyEnd() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
- m_pHandler->OnTagEnd(m_pCurItem->m_pNode,
- CFX_ByteStringC(m_pszData, m_iDataLength),
- m_dwNodePos);
- }
-}
-void CFX_SAXReader::NotifyTargetData() {
- FXSYS_assert(m_pHandler != NULL);
- if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
- m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
- CFX_ByteStringC(m_pszName, m_iNameLength),
- m_dwNodePos);
- } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) {
- m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
- CFX_ByteStringC(m_pszData, m_iDataLength),
- m_dwNodePos);
- }
-}
-void CFX_SAXReader::SkipCurrentNode() {
- if (!m_pCurItem) {
- return;
- }
- m_pCurItem->m_bSkip = TRUE;
-}
-void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler* pHandler) {
- m_pHandler = pHandler;
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <algorithm>
+
+#include "xfa/src/fgas/src/fgas_base.h"
+#include "fx_sax_imp.h"
+
+namespace {
+
+const FX_DWORD kSaxFileBufSize = 32768;
+
+} // namespace
+
+IFX_SAXReader* FX_SAXReader_Create() {
+ return new CFX_SAXReader;
+}
+CFX_SAXFile::CFX_SAXFile()
+ : m_pFile(NULL),
+ m_dwStart(0),
+ m_dwEnd(0),
+ m_dwCur(0),
+ m_pBuf(NULL),
+ m_dwBufSize(0),
+ m_dwBufIndex(0) {}
+FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead* pFile,
+ FX_DWORD dwStart,
+ FX_DWORD dwLen) {
+ FXSYS_assert(m_pFile == NULL && pFile != NULL);
+ FX_DWORD dwSize = pFile->GetSize();
+ if (dwStart >= dwSize) {
+ return FALSE;
+ }
+ if (dwLen == -1 || dwStart + dwLen > dwSize) {
+ dwLen = dwSize - dwStart;
+ }
+ if (dwLen == 0) {
+ return FALSE;
+ }
+ m_dwBufSize = std::min(dwLen, kSaxFileBufSize);
+ m_pBuf = FX_Alloc(uint8_t, m_dwBufSize);
+ if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
+ return FALSE;
+ }
+ m_dwStart = dwStart;
+ m_dwEnd = dwStart + dwLen;
+ m_dwCur = dwStart;
+ m_pFile = pFile;
+ m_dwBufIndex = 0;
+ return TRUE;
+}
+FX_BOOL CFX_SAXFile::ReadNextBlock() {
+ FXSYS_assert(m_pFile != NULL);
+ FX_DWORD dwSize = m_dwEnd - m_dwCur;
+ if (dwSize == 0) {
+ return FALSE;
+ }
+ m_dwBufSize = std::min(dwSize, kSaxFileBufSize);
+ if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) {
+ return FALSE;
+ }
+ m_dwBufIndex = 0;
+ return TRUE;
+}
+void CFX_SAXFile::Reset() {
+ if (m_pBuf) {
+ FX_Free(m_pBuf);
+ m_pBuf = NULL;
+ }
+ m_pFile = NULL;
+}
+CFX_SAXReader::CFX_SAXReader()
+ : m_File(),
+ m_pHandler(nullptr),
+ m_iState(-1),
+ m_pRoot(nullptr),
+ m_pCurItem(nullptr),
+ m_dwItemID(0),
+ m_iDataSize(256),
+ m_iNameSize(256),
+ m_dwParseMode(0),
+ m_pCommentContext(nullptr) {
+ m_pszData = FX_Alloc(uint8_t, m_iDataSize);
+ m_pszName = FX_Alloc(uint8_t, m_iNameSize);
+}
+CFX_SAXReader::~CFX_SAXReader() {
+ Reset();
+ if (m_pszData) {
+ FX_Free(m_pszData);
+ m_pszData = NULL;
+ }
+ if (m_pszName) {
+ FX_Free(m_pszName);
+ m_pszName = NULL;
+ }
+}
+void CFX_SAXReader::Reset() {
+ m_File.Reset();
+ CFX_SAXItem* pItem = m_pRoot;
+ while (pItem) {
+ CFX_SAXItem* pNext = pItem->m_pNext;
+ delete pItem;
+ pItem = pNext;
+ }
+ m_pRoot = NULL;
+ m_pCurItem = NULL;
+ m_dwItemID = 0;
+ m_SkipStack.RemoveAll();
+ m_SkipChar = 0;
+ m_iDataLength = 0;
+ m_iEntityStart = -1;
+ m_iNameLength = 0;
+ m_iDataPos = 0;
+ if (m_pCommentContext) {
+ delete m_pCommentContext;
+ m_pCommentContext = NULL;
+ }
+}
+inline void CFX_SAXReader::Push() {
+ CFX_SAXItem* pNew = new CFX_SAXItem;
+ pNew->m_dwID = ++m_dwItemID;
+ pNew->m_bSkip = m_pCurItem->m_bSkip;
+ pNew->m_pPrev = m_pCurItem;
+ m_pCurItem->m_pNext = pNew;
+ m_pCurItem = pNew;
+}
+inline void CFX_SAXReader::Pop() {
+ if (!m_pCurItem) {
+ return;
+ }
+ CFX_SAXItem* pPrev = m_pCurItem->m_pPrev;
+ pPrev->m_pNext = NULL;
+ delete m_pCurItem;
+ m_pCurItem = pPrev;
+}
+inline void CFX_SAXReader::AppendData(uint8_t ch) {
+ ReallocDataBuffer();
+ m_pszData[m_iDataPos++] = ch;
+}
+inline void CFX_SAXReader::AppendName(uint8_t ch) {
+ ReallocNameBuffer();
+ m_pszName[m_iDataPos++] = ch;
+}
+void CFX_SAXReader::ReallocDataBuffer() {
+ if (m_iDataPos < m_iDataSize) {
+ return;
+ }
+ if (m_iDataSize <= 1024 * 1024) {
+ m_iDataSize *= 2;
+ } else {
+ m_iDataSize += 1024 * 1024;
+ }
+ m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize);
+}
+void CFX_SAXReader::ReallocNameBuffer() {
+ if (m_iDataPos < m_iNameSize) {
+ return;
+ }
+ if (m_iNameSize <= 1024 * 1024) {
+ m_iNameSize *= 2;
+ } else {
+ m_iNameSize += 1024 * 1024;
+ }
+ m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize);
+}
+inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) {
+ return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21;
+}
+int32_t CFX_SAXReader::StartParse(IFX_FileRead* pFile,
+ FX_DWORD dwStart,
+ FX_DWORD dwLen,
+ FX_DWORD dwParseMode) {
+ m_iState = -1;
+ Reset();
+ if (!m_File.StartFile(pFile, dwStart, dwLen)) {
+ return -1;
+ }
+ m_iState = 0;
+ m_eMode = FX_SAXMODE_Text;
+ m_ePrevMode = FX_SAXMODE_Text;
+ m_bCharData = FALSE;
+ m_dwDataOffset = 0;
+ m_pRoot = m_pCurItem = new CFX_SAXItem;
+ m_pCurItem->m_dwID = ++m_dwItemID;
+ m_dwParseMode = dwParseMode;
+ return 0;
+}
+typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)();
+static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = {
+ &CFX_SAXReader::ParseText,
+ &CFX_SAXReader::ParseNodeStart,
+ &CFX_SAXReader::ParseDeclOrComment,
+ &CFX_SAXReader::ParseDeclNode,
+ &CFX_SAXReader::ParseComment,
+ &CFX_SAXReader::ParseCommentContent,
+ &CFX_SAXReader::ParseTagName,
+ &CFX_SAXReader::ParseTagAttributeName,
+ &CFX_SAXReader::ParseTagAttributeEqual,
+ &CFX_SAXReader::ParseTagAttributeValue,
+ &CFX_SAXReader::ParseMaybeClose,
+ &CFX_SAXReader::ParseTagClose,
+ &CFX_SAXReader::ParseTagEnd,
+ &CFX_SAXReader::ParseTargetData,
+};
+int32_t CFX_SAXReader::ContinueParse(IFX_Pause* pPause) {
+ if (m_iState < 0 || m_iState > 99) {
+ return m_iState;
+ }
+ while (m_File.m_dwCur < m_File.m_dwEnd) {
+ FX_DWORD& index = m_File.m_dwBufIndex;
+ FX_DWORD size = m_File.m_dwBufSize;
+ const uint8_t* pBuf = m_File.m_pBuf;
+ while (index < size) {
+ m_CurByte = pBuf[index];
+ (this->*g_FX_SAXReader_LPFParse[m_eMode])();
+ index++;
+ }
+ m_File.m_dwCur += index;
+ m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 /
+ (m_File.m_dwEnd - m_File.m_dwStart);
+ if (m_File.m_dwCur >= m_File.m_dwEnd) {
+ break;
+ }
+ if (!m_File.ReadNextBlock()) {
+ m_iState = -2;
+ break;
+ }
+ m_dwDataOffset = 0;
+ if (pPause && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_iState;
+}
+void CFX_SAXReader::ParseChar(uint8_t ch) {
+ ReallocDataBuffer();
+ m_pszData[m_iDataPos] = ch;
+ if (m_iEntityStart > -1 && ch == ';') {
+ int32_t iSaveEntityStart = m_iEntityStart;
+ CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1,
+ m_iDataPos - m_iEntityStart - 1);
+ int32_t iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == '#') {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) {
+ ch = 0;
+ uint8_t w;
+ if (iLen > 1 && csEntity[1] == 'x') {
+ for (int32_t i = 2; i < iLen; i++) {
+ w = csEntity[i];
+ if (w >= '0' && w <= '9') {
+ ch = (ch << 4) + w - '0';
+ } else if (w >= 'A' && w <= 'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= 'a' && w <= 'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (int32_t i = 1; i < iLen; i++) {
+ w = csEntity[i];
+ if (w < '0' || w > '9') {
+ break;
+ }
+ ch = ch * 10 + w - '0';
+ }
+ }
+ if (ch != 0) {
+ m_pszData[m_iEntityStart++] = ch;
+ }
+ }
+ } else {
+ if (csEntity.Compare("amp") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) {
+ m_pszData[m_iEntityStart++] = '&';
+ }
+ } else if (csEntity.Compare("lt") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) {
+ m_pszData[m_iEntityStart++] = '<';
+ }
+ } else if (csEntity.Compare("gt") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) {
+ m_pszData[m_iEntityStart++] = '>';
+ }
+ } else if (csEntity.Compare("apos") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) {
+ m_pszData[m_iEntityStart++] = '\'';
+ }
+ } else if (csEntity.Compare("quot") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) {
+ m_pszData[m_iEntityStart++] = '\"';
+ }
+ }
+ }
+ }
+ if (iSaveEntityStart != m_iEntityStart) {
+ m_iDataPos = m_iEntityStart;
+ m_iEntityStart = -1;
+ } else {
+ m_iDataPos++;
+ m_iEntityStart = -1;
+ }
+ } else {
+ if (m_iEntityStart < 0 && ch == '&') {
+ m_iEntityStart = m_iDataPos;
+ }
+ m_iDataPos++;
+ }
+}
+void CFX_SAXReader::ParseText() {
+ if (m_CurByte == '<') {
+ if (m_iDataPos > 0) {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyData();
+ }
+ }
+ Push();
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_eMode = FX_SAXMODE_NodeStart;
+ return;
+ }
+ if (m_iDataPos < 1 && SkipSpace(m_CurByte)) {
+ return;
+ }
+ ParseChar(m_CurByte);
+}
+void CFX_SAXReader::ParseNodeStart() {
+ if (m_CurByte == '?') {
+ m_pCurItem->m_eNode = FX_SAXNODE_Instruction;
+ m_eMode = FX_SAXMODE_TagName;
+ return;
+ }
+ if (m_CurByte == '!') {
+ m_eMode = FX_SAXMODE_DeclOrComment;
+ return;
+ }
+ if (m_CurByte == '/') {
+ m_eMode = FX_SAXMODE_TagEnd;
+ return;
+ }
+ if (m_CurByte == '>') {
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ return;
+ }
+ if (m_CurByte > 0x20) {
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ m_pCurItem->m_eNode = FX_SAXNODE_Tag;
+ m_eMode = FX_SAXMODE_TagName;
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseDeclOrComment() {
+ if (m_CurByte == '-') {
+ m_eMode = FX_SAXMODE_Comment;
+ m_pCurItem->m_eNode = FX_SAXNODE_Comment;
+ if (m_pCommentContext == NULL) {
+ m_pCommentContext = new CFX_SAXCommentContext;
+ }
+ m_pCommentContext->m_iHeaderCount = 1;
+ m_pCommentContext->m_iTailCount = 0;
+ } else {
+ m_eMode = FX_SAXMODE_DeclNode;
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ m_SkipChar = '>';
+ m_SkipStack.Add('>');
+ SkipNode();
+ }
+}
+void CFX_SAXReader::ParseComment() {
+ m_pCommentContext->m_iHeaderCount = 2;
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_eMode = FX_SAXMODE_CommentContent;
+}
+void CFX_SAXReader::ParseCommentContent() {
+ if (m_CurByte == '-') {
+ m_pCommentContext->m_iTailCount++;
+ } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyTargetData();
+ }
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ } else {
+ while (m_pCommentContext->m_iTailCount > 0) {
+ AppendData('-');
+ m_pCommentContext->m_iTailCount--;
+ }
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseDeclNode() {
+ SkipNode();
+}
+void CFX_SAXReader::ParseTagName() {
+ if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' ||
+ m_CurByte == '?') {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyEnter();
+ }
+ if (m_CurByte < 0x21) {
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ } else if (m_CurByte == '/' || m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ if (m_pHandler) {
+ NotifyBreak();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ } else {
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseTagAttributeName() {
+ if (m_CurByte < 0x21 || m_CurByte == '=') {
+ if (m_iDataPos < 1 && m_CurByte < 0x21) {
+ return;
+ }
+ m_iNameLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_SkipChar = 0;
+ m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue
+ : FX_SAXMODE_TagAttributeEqual;
+ return;
+ }
+ if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
+ if (m_CurByte == '/' || m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ if (m_pHandler) {
+ NotifyBreak();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ return;
+ }
+ if (m_iDataPos < 1) {
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ }
+ AppendName(m_CurByte);
+}
+void CFX_SAXReader::ParseTagAttributeEqual() {
+ if (m_CurByte == '=') {
+ m_SkipChar = 0;
+ m_eMode = FX_SAXMODE_TagAttributeValue;
+ return;
+ } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_iDataPos = m_iNameLength;
+ AppendName(0x20);
+ m_eMode = FX_SAXMODE_TargetData;
+ ParseTargetData();
+ }
+}
+void CFX_SAXReader::ParseTagAttributeValue() {
+ if (m_SkipChar) {
+ if (m_SkipChar == m_CurByte) {
+ {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyAttribute();
+ }
+ }
+ m_SkipChar = 0;
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ return;
+ }
+ ParseChar(m_CurByte);
+ return;
+ }
+ if (m_CurByte < 0x21) {
+ return;
+ }
+ if (m_iDataPos < 1) {
+ if (m_CurByte == '\'' || m_CurByte == '\"') {
+ m_SkipChar = m_CurByte;
+ }
+ }
+}
+void CFX_SAXReader::ParseMaybeClose() {
+ if (m_CurByte == '>') {
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_iNameLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyTargetData();
+ }
+ }
+ ParseTagClose();
+ m_eMode = FX_SAXMODE_Text;
+ } else if (m_ePrevMode == FX_SAXMODE_TagName) {
+ AppendData('/');
+ m_eMode = FX_SAXMODE_TagName;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTagName();
+ } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) {
+ AppendName('/');
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTagAttributeName();
+ } else if (m_ePrevMode == FX_SAXMODE_TargetData) {
+ AppendName('?');
+ m_eMode = FX_SAXMODE_TargetData;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTargetData();
+ }
+}
+void CFX_SAXReader::ParseTagClose() {
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ if (m_pHandler) {
+ NotifyClose();
+ }
+ Pop();
+}
+void CFX_SAXReader::ParseTagEnd() {
+ if (m_CurByte < 0x21) {
+ return;
+ }
+ if (m_CurByte == '>') {
+ Pop();
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyEnd();
+ }
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ } else {
+ ParseChar(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseTargetData() {
+ if (m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ AppendName(m_CurByte);
+ }
+}
+void CFX_SAXReader::SkipNode() {
+ int32_t iLen = m_SkipStack.GetSize();
+ if (m_SkipChar == '\'' || m_SkipChar == '\"') {
+ if (m_CurByte != m_SkipChar) {
+ return;
+ }
+ iLen--;
+ FXSYS_assert(iLen > -1);
+ m_SkipStack.RemoveAt(iLen, 1);
+ m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
+ return;
+ }
+ switch (m_CurByte) {
+ case '<':
+ m_SkipChar = '>';
+ m_SkipStack.Add('>');
+ break;
+ case '[':
+ m_SkipChar = ']';
+ m_SkipStack.Add(']');
+ break;
+ case '(':
+ m_SkipChar = ')';
+ m_SkipStack.Add(')');
+ break;
+ case '\'':
+ m_SkipChar = '\'';
+ m_SkipStack.Add('\'');
+ break;
+ case '\"':
+ m_SkipChar = '\"';
+ m_SkipStack.Add('\"');
+ break;
+ default:
+ if (m_CurByte == m_SkipChar) {
+ iLen--;
+ m_SkipStack.RemoveAt(iLen, 1);
+ m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
+ if (iLen == 0 && m_CurByte == '>') {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_iDataLength >= 9 &&
+ FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 &&
+ FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]",
+ 2 * sizeof(uint8_t)) == 0) {
+ Pop();
+ m_iDataLength -= 9;
+ m_dwDataOffset += 7;
+ FXSYS_memmove(m_pszData, m_pszData + 7,
+ m_iDataLength * sizeof(uint8_t));
+ m_bCharData = TRUE;
+ if (m_pHandler) {
+ NotifyData();
+ }
+ m_bCharData = FALSE;
+ } else {
+ Pop();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ }
+ break;
+ }
+ if (iLen > 0) {
+ ParseChar(m_CurByte);
+ }
+}
+void CFX_SAXReader::NotifyData() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag)
+ m_pHandler->OnTagData(m_pCurItem->m_pNode,
+ m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text,
+ CFX_ByteStringC(m_pszData, m_iDataLength),
+ m_File.m_dwCur + m_dwDataOffset);
+}
+void CFX_SAXReader::NotifyEnter() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
+ m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pCurItem->m_pNode =
+ m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength),
+ m_pCurItem->m_eNode, m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyAttribute() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
+ m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTagAttribute(m_pCurItem->m_pNode,
+ CFX_ByteStringC(m_pszName, m_iNameLength),
+ CFX_ByteStringC(m_pszData, m_iDataLength));
+ }
+}
+void CFX_SAXReader::NotifyBreak() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
+ m_pHandler->OnTagBreak(m_pCurItem->m_pNode);
+ }
+}
+void CFX_SAXReader::NotifyClose() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
+ m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyEnd() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
+ m_pHandler->OnTagEnd(m_pCurItem->m_pNode,
+ CFX_ByteStringC(m_pszData, m_iDataLength),
+ m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyTargetData() {
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
+ CFX_ByteStringC(m_pszName, m_iNameLength),
+ m_dwNodePos);
+ } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) {
+ m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
+ CFX_ByteStringC(m_pszData, m_iDataLength),
+ m_dwNodePos);
+ }
+}
+void CFX_SAXReader::SkipCurrentNode() {
+ if (!m_pCurItem) {
+ return;
+ }
+ m_pCurItem->m_bSkip = TRUE;
+}
+void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler* pHandler) {
+ m_pHandler = pHandler;
+}
diff --git a/xfa/src/fgas/src/xml/fx_sax_imp.h b/xfa/src/fgas/src/xml/fx_sax_imp.h
index 71be388efd..76809b9503 100644
--- a/xfa/src/fgas/src/xml/fx_sax_imp.h
+++ b/xfa/src/fgas/src/xml/fx_sax_imp.h
@@ -1,134 +1,134 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef _FX_SAX_IMP_
-#define _FX_SAX_IMP_
-
-class CFX_SAXFile {
- public:
- CFX_SAXFile();
- FX_BOOL StartFile(IFX_FileRead* pFile, FX_DWORD dwStart, FX_DWORD dwLen);
- FX_BOOL ReadNextBlock();
- void Reset();
- IFX_FileRead* m_pFile;
- FX_DWORD m_dwStart;
- FX_DWORD m_dwEnd;
- FX_DWORD m_dwCur;
- uint8_t* m_pBuf;
- FX_DWORD m_dwBufSize;
- FX_DWORD m_dwBufIndex;
-};
-enum FX_SAXMODE {
- FX_SAXMODE_Text = 0,
- FX_SAXMODE_NodeStart,
- FX_SAXMODE_DeclOrComment,
- FX_SAXMODE_DeclNode,
- FX_SAXMODE_Comment,
- FX_SAXMODE_CommentContent,
- FX_SAXMODE_TagName,
- FX_SAXMODE_TagAttributeName,
- FX_SAXMODE_TagAttributeEqual,
- FX_SAXMODE_TagAttributeValue,
- FX_SAXMODE_TagMaybeClose,
- FX_SAXMODE_TagClose,
- FX_SAXMODE_TagEnd,
- FX_SAXMODE_TargetData,
- FX_SAXMODE_MAX,
-};
-class CFX_SAXItem {
- public:
- CFX_SAXItem()
- : m_pNode(NULL),
- m_eNode(FX_SAXNODE_Unknown),
- m_dwID(0),
- m_bSkip(FALSE),
- m_pPrev(NULL),
- m_pNext(NULL) {}
- void* m_pNode;
- FX_SAXNODE m_eNode;
- FX_DWORD m_dwID;
- FX_BOOL m_bSkip;
- CFX_SAXItem* m_pPrev;
- CFX_SAXItem* m_pNext;
-};
-class CFX_SAXCommentContext {
- public:
- CFX_SAXCommentContext() : m_iHeaderCount(0), m_iTailCount(0) {}
- int32_t m_iHeaderCount;
- int32_t m_iTailCount;
-};
-class CFX_SAXReader : public IFX_SAXReader {
- public:
- CFX_SAXReader();
- ~CFX_SAXReader();
- virtual void Release() { delete this; }
- virtual int32_t StartParse(IFX_FileRead* pFile,
- FX_DWORD dwStart = 0,
- FX_DWORD dwLen = -1,
- FX_DWORD dwParseMode = 0);
- virtual int32_t ContinueParse(IFX_Pause* pPause = NULL);
- virtual void SkipCurrentNode();
- virtual void SetHandler(IFX_SAXReaderHandler* pHandler);
- void AppendData(uint8_t ch);
- void AppendName(uint8_t ch);
- void ParseText();
- void ParseNodeStart();
- void ParseInstruction();
- void ParseDeclOrComment();
- void ParseDeclNode();
- void ParseComment();
- void ParseCommentContent();
- void ParseTagName();
- void ParseTagAttributeName();
- void ParseTagAttributeEqual();
- void ParseTagAttributeValue();
- void ParseMaybeClose();
- void ParseTagClose();
- void ParseTagEnd();
- void ParseTargetData();
-
- protected:
- CFX_SAXFile m_File;
- IFX_SAXReaderHandler* m_pHandler;
- int32_t m_iState;
- CFX_SAXItem* m_pRoot;
- CFX_SAXItem* m_pCurItem;
- FX_DWORD m_dwItemID;
- FX_SAXMODE m_eMode;
- FX_SAXMODE m_ePrevMode;
- FX_BOOL m_bCharData;
- uint8_t m_CurByte;
- FX_DWORD m_dwDataOffset;
- CFX_ByteArray m_SkipStack;
- uint8_t m_SkipChar;
- FX_DWORD m_dwNodePos;
- uint8_t* m_pszData;
- int32_t m_iDataSize;
- int32_t m_iDataLength;
- int32_t m_iEntityStart;
- int32_t m_iDataPos;
- uint8_t* m_pszName;
- int32_t m_iNameSize;
- int32_t m_iNameLength;
- FX_DWORD m_dwParseMode;
- CFX_SAXCommentContext* m_pCommentContext;
- void Reset();
- void Push();
- void Pop();
- FX_BOOL SkipSpace(uint8_t ch);
- void SkipNode();
- void NotifyData();
- void NotifyEnter();
- void NotifyAttribute();
- void NotifyBreak();
- void NotifyClose();
- void NotifyEnd();
- void NotifyTargetData();
- void ReallocDataBuffer();
- void ReallocNameBuffer();
- void ParseChar(uint8_t ch);
-};
-#endif
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_SAX_IMP_
+#define _FX_SAX_IMP_
+
+class CFX_SAXFile {
+ public:
+ CFX_SAXFile();
+ FX_BOOL StartFile(IFX_FileRead* pFile, FX_DWORD dwStart, FX_DWORD dwLen);
+ FX_BOOL ReadNextBlock();
+ void Reset();
+ IFX_FileRead* m_pFile;
+ FX_DWORD m_dwStart;
+ FX_DWORD m_dwEnd;
+ FX_DWORD m_dwCur;
+ uint8_t* m_pBuf;
+ FX_DWORD m_dwBufSize;
+ FX_DWORD m_dwBufIndex;
+};
+enum FX_SAXMODE {
+ FX_SAXMODE_Text = 0,
+ FX_SAXMODE_NodeStart,
+ FX_SAXMODE_DeclOrComment,
+ FX_SAXMODE_DeclNode,
+ FX_SAXMODE_Comment,
+ FX_SAXMODE_CommentContent,
+ FX_SAXMODE_TagName,
+ FX_SAXMODE_TagAttributeName,
+ FX_SAXMODE_TagAttributeEqual,
+ FX_SAXMODE_TagAttributeValue,
+ FX_SAXMODE_TagMaybeClose,
+ FX_SAXMODE_TagClose,
+ FX_SAXMODE_TagEnd,
+ FX_SAXMODE_TargetData,
+ FX_SAXMODE_MAX,
+};
+class CFX_SAXItem {
+ public:
+ CFX_SAXItem()
+ : m_pNode(NULL),
+ m_eNode(FX_SAXNODE_Unknown),
+ m_dwID(0),
+ m_bSkip(FALSE),
+ m_pPrev(NULL),
+ m_pNext(NULL) {}
+ void* m_pNode;
+ FX_SAXNODE m_eNode;
+ FX_DWORD m_dwID;
+ FX_BOOL m_bSkip;
+ CFX_SAXItem* m_pPrev;
+ CFX_SAXItem* m_pNext;
+};
+class CFX_SAXCommentContext {
+ public:
+ CFX_SAXCommentContext() : m_iHeaderCount(0), m_iTailCount(0) {}
+ int32_t m_iHeaderCount;
+ int32_t m_iTailCount;
+};
+class CFX_SAXReader : public IFX_SAXReader {
+ public:
+ CFX_SAXReader();
+ ~CFX_SAXReader();
+ virtual void Release() { delete this; }
+ virtual int32_t StartParse(IFX_FileRead* pFile,
+ FX_DWORD dwStart = 0,
+ FX_DWORD dwLen = -1,
+ FX_DWORD dwParseMode = 0);
+ virtual int32_t ContinueParse(IFX_Pause* pPause = NULL);
+ virtual void SkipCurrentNode();
+ virtual void SetHandler(IFX_SAXReaderHandler* pHandler);
+ void AppendData(uint8_t ch);
+ void AppendName(uint8_t ch);
+ void ParseText();
+ void ParseNodeStart();
+ void ParseInstruction();
+ void ParseDeclOrComment();
+ void ParseDeclNode();
+ void ParseComment();
+ void ParseCommentContent();
+ void ParseTagName();
+ void ParseTagAttributeName();
+ void ParseTagAttributeEqual();
+ void ParseTagAttributeValue();
+ void ParseMaybeClose();
+ void ParseTagClose();
+ void ParseTagEnd();
+ void ParseTargetData();
+
+ protected:
+ CFX_SAXFile m_File;
+ IFX_SAXReaderHandler* m_pHandler;
+ int32_t m_iState;
+ CFX_SAXItem* m_pRoot;
+ CFX_SAXItem* m_pCurItem;
+ FX_DWORD m_dwItemID;
+ FX_SAXMODE m_eMode;
+ FX_SAXMODE m_ePrevMode;
+ FX_BOOL m_bCharData;
+ uint8_t m_CurByte;
+ FX_DWORD m_dwDataOffset;
+ CFX_ByteArray m_SkipStack;
+ uint8_t m_SkipChar;
+ FX_DWORD m_dwNodePos;
+ uint8_t* m_pszData;
+ int32_t m_iDataSize;
+ int32_t m_iDataLength;
+ int32_t m_iEntityStart;
+ int32_t m_iDataPos;
+ uint8_t* m_pszName;
+ int32_t m_iNameSize;
+ int32_t m_iNameLength;
+ FX_DWORD m_dwParseMode;
+ CFX_SAXCommentContext* m_pCommentContext;
+ void Reset();
+ void Push();
+ void Pop();
+ FX_BOOL SkipSpace(uint8_t ch);
+ void SkipNode();
+ void NotifyData();
+ void NotifyEnter();
+ void NotifyAttribute();
+ void NotifyBreak();
+ void NotifyClose();
+ void NotifyEnd();
+ void NotifyTargetData();
+ void ReallocDataBuffer();
+ void ReallocNameBuffer();
+ void ParseChar(uint8_t ch);
+};
+#endif