diff options
Diffstat (limited to 'xfa/src/fgas/src')
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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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 |