From fdc00a7042d912aafaabddae4d9c84199921ef23 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 28 Oct 2014 23:03:33 -0700 Subject: Merge XFA to PDFium master at 4dc95e7 on 10/28/2014 --- xfa/src/fgas/include/fgas.h | 24 + xfa/src/fgas/include/fx_alg.h | 46 + xfa/src/fgas/include/fx_cpg.h | 233 ++ xfa/src/fgas/include/fx_datetime.h | 470 +++ xfa/src/fgas/include/fx_fnt.h | 170 + xfa/src/fgas/include/fx_lbk.h | 27 + xfa/src/fgas/include/fx_lgg.h | 267 ++ xfa/src/fgas/include/fx_locale.h | 160 + xfa/src/fgas/include/fx_mem.h | 58 + xfa/src/fgas/include/fx_rbk.h | 235 ++ xfa/src/fgas/include/fx_sax.h | 48 + xfa/src/fgas/include/fx_stm.h | 60 + xfa/src/fgas/include/fx_sys.h | 63 + xfa/src/fgas/include/fx_tbk.h | 211 + xfa/src/fgas/include/fx_ucd.h | 23 + xfa/src/fgas/include/fx_utl.h | 797 ++++ xfa/src/fgas/src/crt/codepage/cpcu1250.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1251.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1252.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1253.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1254.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1255.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1256.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1257.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu1258.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu874.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu932.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu936.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu949.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpcu950.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1250.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1251.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1252.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1253.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1254.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1255.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1256.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1257.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi1258.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi874.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi932.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi936.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi949.cpp | 6 + xfa/src/fgas/src/crt/codepage/cphi950.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1250.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1251.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1252.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1253.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1254.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1255.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1256.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1257.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc1258.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc874.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc932.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc936.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc949.cpp | 6 + xfa/src/fgas/src/crt/codepage/cpuc950.cpp | 6 + xfa/src/fgas/src/crt/fx_algorithm.cpp | 315 ++ xfa/src/fgas/src/crt/fx_codepage.cpp | 373 ++ xfa/src/fgas/src/crt/fx_codepage.h | 9 + xfa/src/fgas/src/crt/fx_cpmgr.cpp | 65 + xfa/src/fgas/src/crt/fx_encode.cpp | 189 + xfa/src/fgas/src/crt/fx_memory.cpp | 334 ++ xfa/src/fgas/src/crt/fx_memory.h | 199 + xfa/src/fgas/src/crt/fx_stream.cpp | 1613 ++++++++ xfa/src/fgas/src/crt/fx_stream.h | 405 ++ xfa/src/fgas/src/crt/fx_system.cpp | 236 ++ xfa/src/fgas/src/crt/fx_utils.cpp | 456 +++ xfa/src/fgas/src/crt/fx_utils.h | 32 + xfa/src/fgas/src/fgas_base.h | 12 + xfa/src/fgas/src/font/fx_fontutils.cpp | 236 ++ xfa/src/fgas/src/font/fx_fontutils.h | 19 + xfa/src/fgas/src/font/fx_gdifont.cpp | 532 +++ xfa/src/fgas/src/font/fx_gdifont.h | 89 + xfa/src/fgas/src/font/fx_gefont.cpp | 595 +++ xfa/src/fgas/src/font/fx_gefont.h | 81 + xfa/src/fgas/src/font/fx_stdfontmgr.cpp | 1490 +++++++ xfa/src/fgas/src/font/fx_stdfontmgr.h | 175 + xfa/src/fgas/src/layout/fx_linebreak.cpp | 121 + xfa/src/fgas/src/layout/fx_rtfbreak.cpp | 1522 ++++++++ xfa/src/fgas/src/layout/fx_rtfbreak.h | 180 + xfa/src/fgas/src/layout/fx_textbreak.cpp | 1653 ++++++++ xfa/src/fgas/src/layout/fx_textbreak.h | 171 + xfa/src/fgas/src/layout/fx_unicode.cpp | 146 + xfa/src/fgas/src/layout/fx_unicode.h | 15 + xfa/src/fgas/src/localization/fx_datetime.cpp | 548 +++ xfa/src/fgas/src/localization/fx_locale.cpp | 4954 ++++++++++++++++++++++++ xfa/src/fgas/src/localization/fx_localeimp.h | 74 + xfa/src/fgas/src/localization/fx_localemgr.cpp | 100 + xfa/src/fgas/src/localization/fx_localemgr.h | 27 + xfa/src/fgas/src/xml/fx_sax_imp.cpp | 720 ++++ xfa/src/fgas/src/xml/fx_sax_imp.h | 140 + 93 files changed, 20970 insertions(+) create mode 100644 xfa/src/fgas/include/fgas.h create mode 100644 xfa/src/fgas/include/fx_alg.h create mode 100644 xfa/src/fgas/include/fx_cpg.h create mode 100644 xfa/src/fgas/include/fx_datetime.h create mode 100644 xfa/src/fgas/include/fx_fnt.h create mode 100644 xfa/src/fgas/include/fx_lbk.h create mode 100644 xfa/src/fgas/include/fx_lgg.h create mode 100644 xfa/src/fgas/include/fx_locale.h create mode 100644 xfa/src/fgas/include/fx_mem.h create mode 100644 xfa/src/fgas/include/fx_rbk.h create mode 100644 xfa/src/fgas/include/fx_sax.h create mode 100644 xfa/src/fgas/include/fx_stm.h create mode 100644 xfa/src/fgas/include/fx_sys.h create mode 100644 xfa/src/fgas/include/fx_tbk.h create mode 100644 xfa/src/fgas/include/fx_ucd.h create mode 100644 xfa/src/fgas/include/fx_utl.h create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1250.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1251.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1252.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1253.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1254.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1255.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1256.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1257.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu1258.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu874.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu932.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu936.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu949.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpcu950.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1250.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1251.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1252.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1253.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1254.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1255.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1256.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1257.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi1258.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi874.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi932.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi936.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi949.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cphi950.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1250.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1251.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1252.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1253.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1254.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1255.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1256.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1257.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc1258.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc874.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc932.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc936.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc949.cpp create mode 100644 xfa/src/fgas/src/crt/codepage/cpuc950.cpp create mode 100644 xfa/src/fgas/src/crt/fx_algorithm.cpp create mode 100644 xfa/src/fgas/src/crt/fx_codepage.cpp create mode 100644 xfa/src/fgas/src/crt/fx_codepage.h create mode 100644 xfa/src/fgas/src/crt/fx_cpmgr.cpp create mode 100644 xfa/src/fgas/src/crt/fx_encode.cpp create mode 100644 xfa/src/fgas/src/crt/fx_memory.cpp create mode 100644 xfa/src/fgas/src/crt/fx_memory.h create mode 100644 xfa/src/fgas/src/crt/fx_stream.cpp create mode 100644 xfa/src/fgas/src/crt/fx_stream.h create mode 100644 xfa/src/fgas/src/crt/fx_system.cpp create mode 100644 xfa/src/fgas/src/crt/fx_utils.cpp create mode 100644 xfa/src/fgas/src/crt/fx_utils.h create mode 100644 xfa/src/fgas/src/fgas_base.h create mode 100644 xfa/src/fgas/src/font/fx_fontutils.cpp create mode 100644 xfa/src/fgas/src/font/fx_fontutils.h create mode 100644 xfa/src/fgas/src/font/fx_gdifont.cpp create mode 100644 xfa/src/fgas/src/font/fx_gdifont.h create mode 100644 xfa/src/fgas/src/font/fx_gefont.cpp create mode 100644 xfa/src/fgas/src/font/fx_gefont.h create mode 100644 xfa/src/fgas/src/font/fx_stdfontmgr.cpp create mode 100644 xfa/src/fgas/src/font/fx_stdfontmgr.h create mode 100644 xfa/src/fgas/src/layout/fx_linebreak.cpp create mode 100644 xfa/src/fgas/src/layout/fx_rtfbreak.cpp create mode 100644 xfa/src/fgas/src/layout/fx_rtfbreak.h create mode 100644 xfa/src/fgas/src/layout/fx_textbreak.cpp create mode 100644 xfa/src/fgas/src/layout/fx_textbreak.h create mode 100644 xfa/src/fgas/src/layout/fx_unicode.cpp create mode 100644 xfa/src/fgas/src/layout/fx_unicode.h create mode 100644 xfa/src/fgas/src/localization/fx_datetime.cpp create mode 100644 xfa/src/fgas/src/localization/fx_locale.cpp create mode 100644 xfa/src/fgas/src/localization/fx_localeimp.h create mode 100644 xfa/src/fgas/src/localization/fx_localemgr.cpp create mode 100644 xfa/src/fgas/src/localization/fx_localemgr.h create mode 100644 xfa/src/fgas/src/xml/fx_sax_imp.cpp create mode 100644 xfa/src/fgas/src/xml/fx_sax_imp.h (limited to 'xfa/src/fgas') diff --git a/xfa/src/fgas/include/fgas.h b/xfa/src/fgas/include/fgas.h new file mode 100644 index 0000000000..8f085e4791 --- /dev/null +++ b/xfa/src/fgas/include/fgas.h @@ -0,0 +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 _FGAS_ +#define _FGAS_ +#include "fx_sys.h" +#include "fx_mem.h" +#include "fx_lgg.h" +#include "fx_utl.h" +#include "fx_alg.h" +#include "fx_cpg.h" +#include "fx_stm.h" +#include "fx_datetime.h" +#include "fx_locale.h" +#include "fx_sax.h" +#include "fx_fnt.h" +#include "fx_ucd.h" +#include "fx_lbk.h" +#include "fx_tbk.h" +#include "fx_rbk.h" +#endif diff --git a/xfa/src/fgas/include/fx_alg.h b/xfa/src/fgas/include/fx_alg.h new file mode 100644 index 0000000000..ed946641f2 --- /dev/null +++ b/xfa/src/fgas/include/fx_alg.h @@ -0,0 +1,46 @@ +// 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_ALGORITHM +#define _FX_ALGORITHM +#define FX_IsOdd(a) ((a) & 1) +#ifdef __cplusplus +extern "C" { +#endif +FX_INT32 FX_Base64EncodeA(FX_LPCBYTE pSrc, FX_INT32 iSrcLen, FX_LPSTR pDst); +FX_INT32 FX_Base64DecodeA(FX_LPCSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst); +FX_INT32 FX_Base64DecodeW(FX_LPCWSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst); +FX_BYTE FX_Hex2Dec(FX_BYTE hexHigh, FX_BYTE hexLow); +FX_INT32 FX_SeparateStringW(FX_LPCWSTR pStr, FX_INT32 iStrLen, FX_WCHAR delimiter, CFX_WideStringArray &pieces); +#ifdef __cplusplus +}; +#endif +template +class CFX_DSPATemplate +{ +public: + FX_INT32 Lookup(const baseType &find, const baseType *pArray, FX_INT32 iCount) + { + FXSYS_assert(pArray != NULL); + if (iCount < 1) { + return -1; + } + FX_INT32 iStart = 0, iEnd = iCount - 1, iMid; + do { + iMid = (iStart + iEnd) / 2; + const baseType &v = pArray[iMid]; + if (find == v) { + return iMid; + } else if (find < v) { + iEnd = iMid - 1; + } else { + iStart = iMid + 1; + } + } while (iStart <= iEnd); + return -1; + } +}; +#endif diff --git a/xfa/src/fgas/include/fx_cpg.h b/xfa/src/fgas/include/fx_cpg.h new file mode 100644 index 0000000000..43c6520152 --- /dev/null +++ b/xfa/src/fgas/include/fx_cpg.h @@ -0,0 +1,233 @@ +// 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_CODEPAGE +#define _FX_CODEPAGE +class IFX_CodePage; +#define FX_CODEPAGE_DefANSI 0 +#define FX_CODEPAGE_DefOEM 1 +#define FX_CODEPAGE_DefMAC 2 +#define FX_CODEPAGE_Thread 3 +#define FX_CODEPAGE_Symbol 42 +#define FX_CODEPAGE_MSDOS_US 437 +#define FX_CODEPAGE_Arabic_ASMO708 708 +#define FX_CODEPAGE_Arabic_ASMO449Plus 709 +#define FX_CODEPAGE_Arabic_Transparent 710 +#define FX_CODEPAGE_Arabic_NafithaEnhanced 711 +#define FX_CODEPAGE_Arabic_TransparentASMO 720 +#define FX_CODEPAGE_MSDOS_Greek1 737 +#define FX_CODEPAGE_MSDOS_Baltic 775 +#define FX_CODEPAGE_MSWin31_WesternEuropean 819 +#define FX_CODEPAGE_MSDOS_WesternEuropean 850 +#define FX_CODEPAGE_MSDOS_EasternEuropean 852 +#define FX_CODEPAGE_MSDOS_Latin3 853 +#define FX_CODEPAGE_MSDOS_Cyrillic 855 +#define FX_CODEPAGE_MSDOS_Turkish 857 +#define FX_CODEPAGE_MSDOS_Latin1Euro 858 +#define FX_CODEPAGE_MSDOS_Portuguese 860 +#define FX_CODEPAGE_MSDOS_Icelandic 861 +#define FX_CODEPAGE_MSDOS_Hebrew 862 +#define FX_CODEPAGE_MSDOS_FrenchCanadian 863 +#define FX_CODEPAGE_MSDOS_Arabic 864 +#define FX_CODEPAGE_MSDOS_Norwegian 865 +#define FX_CODEPAGE_MSDOS_Russian 866 +#define FX_CODEPAGE_MSDOS_Greek2 869 +#define FX_CODEPAGE_MSDOS_Thai 874 +#define FX_CODEPAGE_MSDOS_KamenickyCS 895 +#define FX_CODEPAGE_ShiftJIS 932 +#define FX_CODEPAGE_ChineseSimplified 936 +#define FX_CODEPAGE_Korean 949 +#define FX_CODEPAGE_ChineseTraditional 950 +#define FX_CODEPAGE_UTF16LE 1200 +#define FX_CODEPAGE_UTF16BE 1201 +#define FX_CODEPAGE_MSWin_EasternEuropean 1250 +#define FX_CODEPAGE_MSWin_Cyrillic 1251 +#define FX_CODEPAGE_MSWin_WesternEuropean 1252 +#define FX_CODEPAGE_MSWin_Greek 1253 +#define FX_CODEPAGE_MSWin_Turkish 1254 +#define FX_CODEPAGE_MSWin_Hebrew 1255 +#define FX_CODEPAGE_MSWin_Arabic 1256 +#define FX_CODEPAGE_MSWin_Baltic 1257 +#define FX_CODEPAGE_MSWin_Vietnamese 1258 +#define FX_CODEPAGE_Johab 1361 +#define FX_CODEPAGE_MAC_Roman 10000 +#define FX_CODEPAGE_MAC_ShiftJIS 10001 +#define FX_CODEPAGE_MAC_ChineseTraditional 10002 +#define FX_CODEPAGE_MAC_Korean 10003 +#define FX_CODEPAGE_MAC_Arabic 10004 +#define FX_CODEPAGE_MAC_Hebrew 10005 +#define FX_CODEPAGE_MAC_Greek 10006 +#define FX_CODEPAGE_MAC_Cyrillic 10007 +#define FX_CODEPAGE_MAC_ChineseSimplified 10008 +#define FX_CODEPAGE_MAC_Thai 10021 +#define FX_CODEPAGE_MAC_EasternEuropean 10029 +#define FX_CODEPAGE_MAC_Turkish 10081 +#define FX_CODEPAGE_UTF32LE 12000 +#define FX_CODEPAGE_UTF32BE 12001 +#define FX_CODEPAGE_ISO8859_1 28591 +#define FX_CODEPAGE_ISO8859_2 28592 +#define FX_CODEPAGE_ISO8859_3 28593 +#define FX_CODEPAGE_ISO8859_4 28594 +#define FX_CODEPAGE_ISO8859_5 28595 +#define FX_CODEPAGE_ISO8859_6 28596 +#define FX_CODEPAGE_ISO8859_7 28597 +#define FX_CODEPAGE_ISO8859_8 28598 +#define FX_CODEPAGE_ISO8859_9 28599 +#define FX_CODEPAGE_ISO8859_10 28600 +#define FX_CODEPAGE_ISO8859_11 28601 +#define FX_CODEPAGE_ISO8859_12 28602 +#define FX_CODEPAGE_ISO8859_13 28603 +#define FX_CODEPAGE_ISO8859_14 28604 +#define FX_CODEPAGE_ISO8859_15 28605 +#define FX_CODEPAGE_ISO8859_16 28606 +#define FX_CODEPAGE_ISCII_Devanagari 57002 +#define FX_CODEPAGE_ISCII_Bengali 57003 +#define FX_CODEPAGE_ISCII_Tamil 57004 +#define FX_CODEPAGE_ISCII_Telugu 57005 +#define FX_CODEPAGE_ISCII_Assamese 57006 +#define FX_CODEPAGE_ISCII_Oriya 57007 +#define FX_CODEPAGE_ISCII_Kannada 57008 +#define FX_CODEPAGE_ISCII_Malayalam 57009 +#define FX_CODEPAGE_ISCII_Gujarati 57010 +#define FX_CODEPAGE_ISCII_Punjabi 57011 +#define FX_CODEPAGE_UTF7 65000 +#define FX_CODEPAGE_UTF8 65001 +#define FX_CHARSET_ANSI 0 +#define FX_CHARSET_Default 1 +#define FX_CHARSET_Symbol 2 +#define FX_CHARSET_MAC_Roman 77 +#define FX_CHARSET_MAC_ShiftJIS 78 +#define FX_CHARSET_MAC_Korean 79 +#define FX_CHARSET_MAC_ChineseSimplified 80 +#define FX_CHARSET_MAC_ChineseTriditional 81 +#define FX_CHARSET_MAC_Johab 82 +#define FX_CHARSET_MAC_Hebrew 83 +#define FX_CHARSET_MAC_Arabic 84 +#define FX_CHARSET_MAC_Greek 85 +#define FX_CHARSET_MAC_Turkish 86 +#define FX_CHARSET_MAC_Thai 87 +#define FX_CHARSET_MAC_EasternEuropean 88 +#define FX_CHARSET_MAC_Cyrillic 89 +#define FX_CHARSET_ShiftJIS 128 +#define FX_CHARSET_Korean 129 +#define FX_CHARSET_Johab 130 +#define FX_CHARSET_ChineseSimplified 134 +#define FX_CHARSET_ChineseTriditional 136 +#define FX_CHARSET_MSWin_Greek 161 +#define FX_CHARSET_MSWin_Turkish 162 +#define FX_CHARSET_MSWin_Vietnamese 163 +#define FX_CHARSET_MSWin_Hebrew 177 +#define FX_CHARSET_MSWin_Arabic 178 +#define FX_CHARSET_ArabicTraditional 179 +#define FX_CHARSET_ArabicUser 180 +#define FX_CHARSET_HebrewUser 181 +#define FX_CHARSET_MSWin_Baltic 186 +#define FX_CHARSET_MSWin_Cyrillic 204 +#define FX_CHARSET_Thai 222 +#define FX_CHARSET_MSWin_EasterEuropean 238 +#define FX_CHARSET_US 254 +#define FX_CHARSET_OEM 255 +FX_WORD FX_GetCodePageFromCharset(FX_BYTE charset); +FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage); +FX_WORD FX_GetCodePageFromStringA(FX_LPCSTR pStr, FX_INT32 iLength); +FX_WORD FX_GetCodePageFormStringW(FX_LPCWSTR pStr, FX_INT32 iLength); +FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage); +void FX_SwapByteOrder(FX_LPWSTR pStr, FX_INT32 iLength); +void FX_SwapByteOrderCopy(FX_LPCWSTR pSrc, FX_LPWSTR pDst, FX_INT32 iLength); +void FX_UTF16ToWChar(FX_LPVOID pBuffer, FX_INT32 iLength); +void FX_UTF16ToWCharCopy(const FX_WORD *pUTF16, FX_LPWSTR pWChar, FX_INT32 iLength); +void FX_WCharToUTF16(FX_LPVOID pBuffer, FX_INT32 iLength); +void FX_WCharToUTF16Copy(FX_LPCWSTR pWChar, FX_WORD *pUTF16, FX_INT32 iLength); +FX_INT32 FX_DecodeString(FX_WORD wCodePage, FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen, FX_BOOL bErrBreak = FALSE); +FX_INT32 FX_UTF8Decode(FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen); +enum FX_CODESYSTEM { + FX_MBCS = 0, + FX_SBCS , + FX_DBCS , +}; +typedef struct _FX_CODEPAGE_HEADER { + FX_UINT16 uCPID; + FX_UINT8 uMinCharBytes; + FX_UINT8 uMaxCharBytes; + FX_CODESYSTEM eCPType; + FX_BOOL bHasLeadByte; + FX_WCHAR wMinChar; + FX_WCHAR wMaxChar; + FX_WCHAR wDefChar; + FX_WCHAR wMinUnicode; + FX_WCHAR wMaxUnicode; + FX_WCHAR wDefUnicode; +} FX_CODEPAGE_HEADER; +#define FX_CPMAPTYPE_Consecution 1 +#define FX_CPMAPTYPE_Strict 2 +#define FX_CPMAPTYPE_NoMapping 3 +#define FX_CPMAPTYPE_Delta 4 +typedef struct _FX_CPCU_MAPTABLE1 { + FX_UINT16 uMapType; + FX_UINT16 uUniocde; +} FX_CPCU_MAPTABLE1; +typedef struct _FX_CPCU_MAPTABLE2 { + FX_UINT8 uTrailByte; + FX_UINT8 uMapType; + FX_UINT16 uOffset; +} FX_CPCU_MAPTABLE2; +typedef struct _FX_CPCU_MAPINFO { + FX_CPCU_MAPTABLE1 *pMapTable1; + FX_CPCU_MAPTABLE2 *pMapTable2; + FX_LPCBYTE pMapData; +} FX_CPCU_MAPINFO; +typedef struct _FX_CPUC_MAPTABLE { + FX_UINT16 uStartUnicode; + FX_UINT16 uEndUnicode; + FX_UINT16 uMapType; + FX_UINT16 uOffset; +} FX_CPUC_MAPTABLE; +typedef struct _FX_CPUC_MAPINFO { + FX_UINT32 uMapCount; + FX_CPUC_MAPTABLE *pMapTable; + FX_LPCBYTE pMapData; +} FX_CPUC_MAPINFO; +typedef struct _FX_CODEPAGE { + FX_CODEPAGE_HEADER const *pCPHeader; + FX_CPCU_MAPINFO const *pCPCUMapInfo; + FX_CPUC_MAPINFO const *pCPUCMapInfo; +} FX_CODEPAGE, * FX_LPCODEPAGE; +typedef FX_CODEPAGE const * FX_LPCCODEPAGE; +typedef struct _FX_STR2CPHASH { + FX_UINT32 uHash; + FX_UINT32 uCodePage; +} FX_STR2CPHASH; +typedef struct _FX_CHARSET_MAP { + FX_UINT16 charset; + FX_UINT16 codepage; +} FX_CHARSET_MAP; +typedef struct _FX_LANG2CPMAP { + FX_WORD wLanguage; + FX_WORD wCodepage; +} FX_LANG2CPMAP; +class IFX_CodePage +{ +public: + static IFX_CodePage* Create(FX_WORD wCodePage); + virtual void Release() = 0; + virtual FX_WORD GetCodePageNumber() const = 0; + virtual FX_CODESYSTEM GetCodeSystemType() const = 0; + virtual FX_BOOL HasLeadByte() const = 0; + virtual FX_BOOL IsLeadByte(FX_BYTE byte) const = 0; + virtual FX_INT32 GetMinBytesPerChar() const = 0; + virtual FX_INT32 GetMaxBytesPerChar() const = 0; + virtual FX_WCHAR GetMinCharcode() const = 0; + virtual FX_WCHAR GetMaxCharcode() const = 0; + virtual FX_WCHAR GetDefCharcode() const = 0; + virtual FX_WCHAR GetMinUnicode() const = 0; + virtual FX_WCHAR GetMaxUnicode() const = 0; + virtual FX_WCHAR GetDefUnicode() const = 0; + virtual FX_BOOL IsValidCharcode(FX_WORD wCharcode) const = 0; + virtual FX_WCHAR GetUnicode(FX_WORD wCharcode) const = 0; + virtual FX_BOOL IsValidUnicode(FX_WCHAR wUnicode) const = 0; + virtual FX_WORD GetCharcode(FX_WCHAR wUnicode) const = 0; +}; +#endif diff --git a/xfa/src/fgas/include/fx_datetime.h b/xfa/src/fgas/include/fx_datetime.h new file mode 100644 index 0000000000..dd0a5d6147 --- /dev/null +++ b/xfa/src/fgas/include/fx_datetime.h @@ -0,0 +1,470 @@ +// 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_DATETIME_H_ +#define _FX_DATETIME_H_ +class CFX_Unitime; +class CFX_DateTime; +typedef FX_INT64 FX_UNITIME; +enum FX_WEEKDAY { + FX_Sunday = 0, + FX_Monday , + FX_Tuesday , + FX_Wednesday , + FX_Thursday , + FX_Friday , + FX_Saturday , +}; +FX_BOOL FX_IsLeapYear(FX_INT32 iYear); +FX_INT32 FX_DaysInYear(FX_INT32 iYear); +FX_BYTE FX_DaysInMonth(FX_INT32 iYear, FX_BYTE iMonth); +class CFX_Unitime : public CFX_Object +{ +public: + CFX_Unitime() + { + m_iUnitime = 0; + } + CFX_Unitime(FX_UNITIME iUnitime) + { + m_iUnitime = iUnitime; + } + CFX_Unitime(const CFX_Unitime &unitime) + { + m_iUnitime = unitime.m_iUnitime; + } + operator FX_UNITIME * () + { + return &m_iUnitime; + } + operator FX_UNITIME const * () const + { + return &m_iUnitime; + } + operator FX_UNITIME& () + { + return m_iUnitime; + } + operator const FX_UNITIME& () const + { + return m_iUnitime; + } + CFX_Unitime& operator = (const CFX_Unitime &t) + { + m_iUnitime = t.m_iUnitime; + return *this; + } + CFX_Unitime& operator = (FX_UNITIME t) + { + m_iUnitime = t; + return *this; + } + CFX_Unitime& operator += (const CFX_Unitime &t) + { + m_iUnitime += t.m_iUnitime; + return *this; + } + CFX_Unitime& operator += (FX_UNITIME t) + { + m_iUnitime += t; + return *this; + } + CFX_Unitime& operator -= (const CFX_Unitime &t) + { + m_iUnitime -= t.m_iUnitime; + return *this; + } + CFX_Unitime& operator -= (FX_UNITIME t) + { + m_iUnitime -= t; + return *this; + } + void Now(); + void SetGMTime(); + void Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour = 0, FX_BYTE minute = 0, FX_BYTE second = 0, FX_WORD millisecond = 0); + void Set(FX_UNITIME t); + FX_INT32 GetYear() const; + FX_BYTE GetMonth() const; + FX_BYTE GetDay() const; + FX_WEEKDAY GetDayOfWeek() const; + FX_WORD GetDayOfYear() const; + FX_INT64 GetDayOfAD() const; + FX_BYTE GetHour() const; + FX_BYTE GetMinute() const; + FX_BYTE GetSecond() const; + FX_WORD GetMillisecond() const; + FX_BOOL AddYears(FX_INT32 iYears); + FX_BOOL AddMonths(FX_INT32 iMonths); + FX_BOOL AddDays(FX_INT32 iDays); + FX_BOOL AddHours(FX_INT32 iHours); + FX_BOOL AddMinutes(FX_INT32 iMinutes); + FX_BOOL AddSeconds(FX_INT32 iSeconds); + FX_BOOL AddMilliseconds(FX_INT32 iMilliseconds); + friend CFX_Unitime operator + (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return CFX_Unitime(t1.m_iUnitime + t2.m_iUnitime); + } + friend CFX_Unitime operator + (const CFX_Unitime &t1, FX_UNITIME t2) + { + return CFX_Unitime(t1.m_iUnitime + t2); + } + friend CFX_Unitime operator + (FX_UNITIME t1, const CFX_Unitime &t2) + { + return CFX_Unitime(t1 + t2.m_iUnitime); + } + friend CFX_Unitime operator - (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return CFX_Unitime(t1.m_iUnitime + t2.m_iUnitime); + } + friend CFX_Unitime operator - (const CFX_Unitime &t1, FX_UNITIME t2) + { + return CFX_Unitime(t1.m_iUnitime + t2); + } + friend CFX_Unitime operator - (FX_UNITIME t1, const CFX_Unitime &t2) + { + return CFX_Unitime(t1 + t2.m_iUnitime); + } + friend FX_BOOL operator == (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime == t2.m_iUnitime; + } + friend FX_BOOL operator == (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime == t2; + } + friend FX_BOOL operator == (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 == t2.m_iUnitime; + } + friend FX_BOOL operator != (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime != t2.m_iUnitime; + } + friend FX_BOOL operator != (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime != t2; + } + friend FX_BOOL operator != (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 != t2.m_iUnitime; + } + friend FX_BOOL operator > (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime > t2.m_iUnitime; + } + friend FX_BOOL operator > (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime > t2; + } + friend FX_BOOL operator > (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 > t2.m_iUnitime; + } + friend FX_BOOL operator >= (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime >= t2.m_iUnitime; + } + friend FX_BOOL operator >= (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime >= t2; + } + friend FX_BOOL operator >= (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 >= t2.m_iUnitime; + } + friend FX_BOOL operator < (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime < t2.m_iUnitime; + } + friend FX_BOOL operator < (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime < t2; + } + friend FX_BOOL operator < (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 < t2.m_iUnitime; + } + friend FX_BOOL operator <= (const CFX_Unitime &t1, const CFX_Unitime &t2) + { + return t1.m_iUnitime <= t2.m_iUnitime; + } + friend FX_BOOL operator <= (const CFX_Unitime &t1, FX_UNITIME t2) + { + return t1.m_iUnitime <= t2; + } + friend FX_BOOL operator <= (FX_UNITIME t1, const CFX_Unitime &t2) + { + return t1 <= t2.m_iUnitime; + } +private: + FX_UNITIME m_iUnitime; +}; +#if _FX_OS_ != _FX_ANDROID_ +#pragma pack(push, 1) +#endif +typedef struct _FX_DATE { + FX_INT32 year; + FX_BYTE month; + FX_BYTE day; +} FX_DATE, * FX_LPDATE; +typedef FX_DATE const * FX_LPCDATE; +typedef struct _FX_TIME { + FX_BYTE hour; + FX_BYTE minute; + FX_BYTE second; + FX_WORD millisecond; +} FX_TIME, * FX_LPTIME; +typedef FX_TIME const * FX_LPCTIME; +typedef struct _FX_TIMEZONE { + FX_INT8 tzHour; + FX_BYTE tzMinute; +} FX_TIMEZONE, * FX_LPTIMEZONE; +typedef FX_TIMEZONE const * FX_LPCTIMEZONE; +typedef struct _FX_DATETIME { + union { + struct { + FX_INT32 year; + FX_BYTE month; + FX_BYTE day; + } sDate; + FX_DATE aDate; + } Date; + union { + struct { + FX_BYTE hour; + FX_BYTE minute; + FX_BYTE second; + FX_WORD millisecond; + } sTime; + FX_TIME aTime; + } Time; +} FX_DATETIME, * FX_LPDATETIME; +typedef FX_DATETIME const * FX_LPCDATETIME; +typedef struct _FX_DATETIMEZONE { + union { + struct { + union { + struct { + FX_INT32 year; + FX_BYTE month; + FX_BYTE day; + }; + FX_DATE date; + }; + union { + struct { + FX_BYTE hour; + FX_BYTE minute; + FX_BYTE second; + FX_WORD millisecond; + }; + FX_TIME time; + }; + }; + FX_DATETIME dt; + }; + union { + struct { + FX_INT8 tzHour; + FX_BYTE tzMinute; + }; + FX_TIMEZONE tz; + }; +} FX_DATETIMEZONE, * FX_LPDATETIMEZONE; +typedef FX_DATETIMEZONE const * FX_LPCDATETIMEZONE; +#if _FX_OS_ != _FX_ANDROID_ +#pragma pack(pop) +#endif +class CFX_DateTime : public CFX_Object +{ +public: + CFX_DateTime() {} + CFX_DateTime(const FX_DATETIME &dt) + { + m_DateTime = dt; + } + CFX_DateTime(const CFX_DateTime &dt) + { + m_DateTime = dt.m_DateTime; + } + operator FX_DATETIME * () + { + return &m_DateTime; + } + operator FX_DATETIME const * () const + { + return &m_DateTime; + } + operator FX_DATETIME& () + { + return m_DateTime; + } + operator const FX_DATETIME& () const + { + return m_DateTime; + } + CFX_DateTime& operator = (const CFX_DateTime &dt) + { + m_DateTime = dt.m_DateTime; + return *this; + } + CFX_DateTime& operator = (const FX_DATETIME &dt) + { + m_DateTime = dt; + return *this; + } + CFX_DateTime& operator += (const CFX_DateTime &dt) + { + FromUnitime(ToUnitime() + dt.ToUnitime()); + return *this; + } + CFX_DateTime& operator += (const FX_DATETIME &dt) + { + FromUnitime(ToUnitime() + ((const CFX_DateTime&)dt).ToUnitime()); + return *this; + } + CFX_DateTime& operator -= (const CFX_DateTime &dt) + { + FromUnitime(ToUnitime() - dt.ToUnitime()); + return *this; + } + CFX_DateTime& operator -= (const FX_DATETIME &dt) + { + FromUnitime(ToUnitime() - ((const CFX_DateTime&)dt).ToUnitime()); + return *this; + } + virtual FX_BOOL Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour = 0, FX_BYTE minute = 0, FX_BYTE second = 0, FX_WORD millisecond = 0); + virtual FX_BOOL FromUnitime(FX_UNITIME t); + virtual FX_UNITIME ToUnitime() const; + virtual FX_INT32 GetYear() const; + virtual FX_BYTE GetMonth() const; + virtual FX_BYTE GetDay() const; + virtual FX_WEEKDAY GetDayOfWeek() const; + virtual FX_WORD GetDayOfYear() const; + virtual FX_INT64 GetDayOfAD() const; + virtual FX_BYTE GetHour() const; + virtual FX_BYTE GetMinute() const; + virtual FX_BYTE GetSecond() const; + virtual FX_WORD GetMillisecond() const; + virtual FX_BOOL AddYears(FX_INT32 iYears); + virtual FX_BOOL AddMonths(FX_INT32 iMonths); + virtual FX_BOOL AddDays(FX_INT32 iDays); + virtual FX_BOOL AddHours(FX_INT32 iHours); + virtual FX_BOOL AddMinutes(FX_INT32 iMinutes); + virtual FX_BOOL AddSeconds(FX_INT32 iSeconds); + virtual FX_BOOL AddMilliseconds(FX_INT32 iMilliseconds); + friend CFX_DateTime operator + (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(dt1.ToUnitime() + dt2.ToUnitime()); + return dt; + } + friend CFX_DateTime operator + (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(dt1.ToUnitime() + ((const CFX_DateTime&)dt2).ToUnitime()); + return dt; + } + friend CFX_DateTime operator + (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(((const CFX_DateTime&)dt1).ToUnitime() + dt2.ToUnitime()); + return dt; + } + friend CFX_DateTime operator - (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(dt1.ToUnitime() - dt2.ToUnitime()); + return dt; + } + friend CFX_DateTime operator - (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(dt1.ToUnitime() - ((const CFX_DateTime&)dt2).ToUnitime()); + return dt; + } + friend CFX_DateTime operator - (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + CFX_DateTime dt; + dt.FromUnitime(((const CFX_DateTime&)dt1).ToUnitime() - dt2.ToUnitime()); + return dt; + } + friend FX_BOOL operator == (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return FXSYS_memcmp((FX_LPCDATETIME)dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) == 0; + } + friend FX_BOOL operator == (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return FXSYS_memcmp((FX_LPCDATETIME)dt1, &dt2, sizeof(FX_DATETIME)) == 0; + } + friend FX_BOOL operator == (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return FXSYS_memcmp(&dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) == 0; + } + friend FX_BOOL operator != (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return FXSYS_memcmp((FX_LPCDATETIME)dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) != 0; + } + friend FX_BOOL operator != (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return FXSYS_memcmp((FX_LPCDATETIME)dt1, &dt2, sizeof(FX_DATETIME)) != 0; + } + friend FX_BOOL operator != (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return FXSYS_memcmp(&dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) != 0; + } + friend FX_BOOL operator > (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return dt1.ToUnitime() > dt2.ToUnitime(); + } + friend FX_BOOL operator > (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return dt1.ToUnitime() > ((const CFX_DateTime&)dt2).ToUnitime(); + } + friend FX_BOOL operator > (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return ((const CFX_DateTime&)dt1).ToUnitime() > dt2.ToUnitime(); + } + friend FX_BOOL operator >= (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return dt1.ToUnitime() >= dt2.ToUnitime(); + } + friend FX_BOOL operator >= (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return dt1.ToUnitime() >= ((const CFX_DateTime&)dt2).ToUnitime(); + } + friend FX_BOOL operator >= (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return ((const CFX_DateTime&)dt1).ToUnitime() >= dt2.ToUnitime(); + } + friend FX_BOOL operator < (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return dt1.ToUnitime() < dt2.ToUnitime(); + } + friend FX_BOOL operator < (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return dt1.ToUnitime() < ((const CFX_DateTime&)dt2).ToUnitime(); + } + friend FX_BOOL operator < (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return ((const CFX_DateTime&)dt1).ToUnitime() < dt2.ToUnitime(); + } + friend FX_BOOL operator <= (const CFX_DateTime &dt1, const CFX_DateTime &dt2) + { + return dt1.ToUnitime() <= dt2.ToUnitime(); + } + friend FX_BOOL operator <= (const CFX_DateTime &dt1, const FX_DATETIME &dt2) + { + return dt1.ToUnitime() <= ((const CFX_DateTime&)dt2).ToUnitime(); + } + friend FX_BOOL operator <= (const FX_DATETIME &dt1, const CFX_DateTime &dt2) + { + return ((const CFX_DateTime&)dt1).ToUnitime() <= dt2.ToUnitime(); + } +private: + FX_DATETIME m_DateTime; +}; +#endif diff --git a/xfa/src/fgas/include/fx_fnt.h b/xfa/src/fgas/include/fx_fnt.h new file mode 100644 index 0000000000..d664853df7 --- /dev/null +++ b/xfa/src/fgas/include/fx_fnt.h @@ -0,0 +1,170 @@ +// 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_FONT +#define _FX_FONT +class IFX_Font; +class IFX_FontMgr; +#define FX_FONTSTYLE_Normal 0x00 +#define FX_FONTSTYLE_FixedPitch 0x01 +#define FX_FONTSTYLE_Serif 0x02 +#define FX_FONTSTYLE_Symbolic 0x04 +#define FX_FONTSTYLE_Script 0x08 +#define FX_FONTSTYLE_Italic 0x40 +#define FX_FONTSTYLE_Bold 0x40000 +#define FX_FONTSTYLE_BoldItalic (FX_FONTSTYLE_Bold|FX_FONTSTYLE_Italic) +#define FX_FONTSTYLE_ExactMatch 0x80000000 +#define FX_FONTDECORATION_Underline 0x00000001 +#define FX_FONTDECORATION_Strikeout 0x00000002 +#define FX_FONTDECORATION_Overline 0x00000004 +#define FX_FONTDECORATION_Emphasis 0x00000008 +#define FX_FONTDECORATION_Superscript 0x00000010 +#define FX_FONTDECORATION_Subscript 0x00000020 +#define FX_FONTDECORATION_SmallCapital 0x00000040 +#define FX_FONTDECORATION_Capital 0x00000080 +#define FX_FONTDECORATION_Lowercase 0x000000C0 +#define FX_FONTDECORATION_Raised 0x00000100 +#define FX_FONTDECORATION_Sunken 0x00000200 +#define FX_FONTDECORATION_Shadow 0x00000400 +#define FX_FONTDECORATION_BoundingShape 0x20000000 +#define FX_FONTDECORATION_Hide 0x40000000 +#define FX_FONTDECORATION_StrokeFill 0x80000000 +#define FX_BOUNDINGSHAPE_None 0 +#define FX_BOUNDINGSHAPE_Circle 1 +#define FX_BOUNDINGSHAPE_Square 2 +#define FX_BOUNDINGSHAPE_Triangle 3 +#define FX_BOUNDINGSHAPE_Diamond 4 +class IFX_FontProvider +{ +public: + virtual FX_BOOL GetCharWidth(IFX_Font* pFont, FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE) = 0; +}; +class IFX_Font +{ +public: + static IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage, IFX_FontMgr *pFontMgr); + static IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, IFX_FontMgr *pFontMgr); + static IFX_Font* LoadFont(FX_LPCWSTR pszFileName, IFX_FontMgr *pFontMgr); + static IFX_Font* LoadFont(IFX_Stream *pFontStream, IFX_FontMgr *pFontMgr, FX_BOOL bSaveStream = FALSE); + static IFX_Font* LoadFont(CFX_Font *pExtFont, IFX_FontMgr *pFontMgr, FX_BOOL bTakeOver = FALSE); + virtual void Release() = 0; + virtual IFX_Font* Retain() = 0; + virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0) = 0; + virtual void GetFamilyName(CFX_WideString &wsFamily) const = 0; + virtual void GetPsName(CFX_WideString &wsName) const = 0; + virtual FX_DWORD GetFontStyles() const = 0; + virtual FX_BYTE GetCharSet() const = 0; + virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE) = 0; + virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE) = 0; + virtual FX_INT32 GetAscent() const = 0; + virtual FX_INT32 GetDescent() const = 0; + virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE) = 0; + virtual FX_BOOL GetBBox(CFX_Rect &bbox) = 0; + virtual FX_INT32 GetItalicAngle() const = 0; + virtual void Reset() = 0; + virtual IFX_Font* GetSubstFont(FX_INT32 iGlyphIndex) const = 0; + virtual void* GetDevFont() const = 0; + virtual void SetFontProvider(IFX_FontProvider* pProvider) = 0; +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + virtual void SetLogicalFontStyle(FX_DWORD dwLogFontStyle) = 0; +#endif +}; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +typedef struct _FX_FONTMATCHPARAMS : public CFX_Object { + FX_LPCWSTR pwsFamily; + FX_DWORD dwFontStyles; + FX_DWORD dwUSB; + FX_DWORD dwMatchFlags; + FX_WCHAR wUnicode; + FX_WORD wCodePage; +} FX_FONTMATCHPARAMS, * FX_LPFONTMATCHPARAMS; +typedef FX_FONTMATCHPARAMS const * FX_LPCFONTMATCHPARAMS; +typedef struct _FX_FONTSIGNATURE : public CFX_Target { + FX_DWORD fsUsb[4]; + FX_DWORD fsCsb[2]; +} FX_FONTSIGNATURE; +typedef struct _FX_FONTDESCRIPTOR : public CFX_Target { + FX_WCHAR wsFontFace[32]; + FX_DWORD dwFontStyles; + FX_BYTE uCharSet; + FX_FONTSIGNATURE FontSignature; +} FX_FONTDESCRIPTOR, * FX_LPFONTDESCRIPTOR; +typedef FX_FONTDESCRIPTOR const * FX_LPCFONTDESCRIPTOR; +typedef CFX_MassArrayTemplate CFX_FontDescriptors; +inline FX_BOOL operator == (const FX_FONTDESCRIPTOR &left, const FX_FONTDESCRIPTOR &right) +{ + return left.uCharSet == right.uCharSet + && left.dwFontStyles == right.dwFontStyles + && FXSYS_wcscmp(left.wsFontFace, right.wsFontFace) == 0 + && FXSYS_memcmp(&left.FontSignature, &right.FontSignature, sizeof(FX_FONTSIGNATURE)) == 0; +} +#define FX_FONTMATCHPARA_MacthStyle 0x01 +#define FX_FONTMATCHPARA_MacthFamily 0x02 +#define FX_FONTMATCHPARA_MacthUnicode 0x04 +typedef void (*FX_LPEnumAllFonts)(CFX_FontDescriptors &fonts, FX_LPVOID pUserData, FX_LPCWSTR pwsFaceName, FX_WCHAR wUnicode); +FX_LPEnumAllFonts FX_GetDefFontEnumerator(); +typedef FX_LPCFONTDESCRIPTOR (*FX_LPMatchFont)(FX_LPFONTMATCHPARAMS pParams, const CFX_FontDescriptors &fonts, FX_LPVOID pUserData); +FX_LPMatchFont FX_GetDefFontMatchor(); +class IFX_FontMgr +{ +public: + static IFX_FontMgr* Create(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher = NULL, FX_LPVOID pUserData = NULL); + virtual void Release() = 0; + virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0; + virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength) = 0; + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName) = 0; + virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR pszFontAlias = NULL, FX_DWORD dwFontStyles = 0, FX_WORD wCodePage = 0, FX_BOOL bSaveStream = FALSE) = 0; + virtual IFX_Font* LoadFont(IFX_Font *pSrcFont, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0; + virtual void ClearFontCache() = 0; + virtual void RemoveFont(IFX_Font *pFont) = 0; +}; +#else +class IFX_FontMgrDelegate +{ +public: + virtual IFX_Font* GetDefFontByCodePage(IFX_FontMgr* pFontMgr, FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByCharset(IFX_FontMgr* pFontMgr, FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByUnicode(IFX_FontMgr* pFontMgr, FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByLanguage(IFX_FontMgr* pFontMgr, FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; +}; +class IFX_FontSourceEnum +{ +public: + virtual void Release() = 0; + virtual FX_POSITION GetStartPosition(FX_LPVOID pUserData = NULL) = 0; + virtual IFX_FileAccess* GetNext(FX_POSITION& pos, FX_LPVOID pUserData = NULL) = 0; +}; +IFX_FontSourceEnum* FX_CreateDefaultFontSourceEnum(); +class IFX_FontMgr +{ +public: + static IFX_FontMgr* Create(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate = NULL, FX_LPVOID pUserData = NULL); + virtual void Release() = 0; + virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + inline IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage) + { + return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); + } + virtual IFX_Font* GetFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0; + virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL) = 0; + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL) = 0; + virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL, FX_BOOL bSaveStream = FALSE) = 0; + + virtual void ClearFontCache() = 0; + virtual void RemoveFont(IFX_Font *pFont) = 0; +}; +#endif +#endif diff --git a/xfa/src/fgas/include/fx_lbk.h b/xfa/src/fgas/include/fx_lbk.h new file mode 100644 index 0000000000..3c7aa5d7dd --- /dev/null +++ b/xfa/src/fgas/include/fx_lbk.h @@ -0,0 +1,27 @@ +// 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_LINEBREAK +#define _FX_LINEBREAK +enum FX_LINEBREAKTYPE { + FX_LBT_UNKNOWN = 0x00, + FX_LBT_DIRECT_BRK = 0x1A, + FX_LBT_INDIRECT_BRK = 0x2B, + FX_LBT_COM_INDIRECT_BRK = 0x3C, + FX_LBT_COM_PROHIBITED_BRK = 0x4D, + FX_LBT_PROHIBITED_BRK = 0x5E, + FX_LBT_HANGUL_SPACE_BRK = 0x6F, +}; +#define FX_LBUN FX_LBT_UNKNOWN +#define FX_LBDB FX_LBT_DIRECT_BRK +#define FX_LBIB FX_LBT_INDIRECT_BRK +#define FX_LBCB FX_LBT_COM_INDIRECT_BRK +#define FX_LBCP FX_LBT_COM_PROHIBITED_BRK +#define FX_LBPB FX_LBT_PROHIBITED_BRK +#define FX_LBHS FX_LBT_HANGUL_SPACE_BRK +void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_LINEBREAKTYPE *pBrkType, FX_INT32 iLength); +void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_INT32 iLength, CFX_Int32MassArray &bp); +#endif diff --git a/xfa/src/fgas/include/fx_lgg.h b/xfa/src/fgas/include/fx_lgg.h new file mode 100644 index 0000000000..6f4786e319 --- /dev/null +++ b/xfa/src/fgas/include/fx_lgg.h @@ -0,0 +1,267 @@ +// 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_LANGUAGE +#define _FX_LANGUAGE +#define FX_LANG_Neutral 0x0000 +#define FX_LANG_Invariant 0x007f +#define FX_LANG_UserDefault 0x0400 +#define FX_LANG_SystemDefault 0x0800 +#define FX_LANG_Afrikaans_SouthAfrica 0x0436 +#define FX_LANG_Albanian_Albania 0x041c +#define FX_LANG_Alsatian_France 0x0484 +#define FX_LANG_Amharic_Ethiopia 0x045e +#define FX_LANG_Arabic_Algeria 0x1401 +#define FX_LANG_Arabic_Bahrain 0x3c01 +#define FX_LANG_Arabic_Egypt 0x0c01 +#define FX_LANG_Arabic_Iraq 0x0801 +#define FX_LANG_Arabic_Jordan 0x2c01 +#define FX_LANG_Arabic_Kuwait 0x3401 +#define FX_LANG_Arabic_Lebanon 0x3001 +#define FX_LANG_Arabic_Libya 0x1001 +#define FX_LANG_Arabic_Morocco 0x1801 +#define FX_LANG_Arabic_Oman 0x2001 +#define FX_LANG_Arabic_Qatar 0x4001 +#define FX_LANG_Arabic_SaudiArabia 0x0401 +#define FX_LANG_Arabic_Syria 0x2801 +#define FX_LANG_Arabic_Tunisia 0x1c01 +#define FX_LANG_Arabic_UAE 0x3801 +#define FX_LANG_Arabic_Yemen 0x2401 +#define FX_LANG_Armenian_Armenia 0x042b +#define FX_LANG_Assamese_India 0x044d +#define FX_LANG_Azerbaijan_Cyrillic 0x082c +#define FX_LANG_Azerbaijan_Latin 0x042c +#define FX_LANG_Bashkir_Russia 0x046d +#define FX_LANG_Basque_Basque 0x042d +#define FX_LANG_Belarusian_Belarus 0x0423 +#define FX_LANG_Bengali_Bangladesh 0x0845 +#define FX_LANG_Bengali_India 0x0445 +#define FX_LANG_Bosnia_Herzegovina 0x101a +#define FX_LANG_Bosnian_Cyrillic 0x201a +#define FX_LANG_Bosnian_Latin 0x141a +#define FX_LANG_Breton_France 0x047e +#define FX_LANG_Bulgarian_Bulgaria 0x0402 +#define FX_LANG_Burmese 0x0455 +#define FX_LANG_Catalan_Catalan 0x0403 +#define FX_LANG_Cherokee 0x045c +#define FX_LANG_Chinese_HongKong 0x0c04 +#define FX_LANG_Chinese_Macao 0x1404 +#define FX_LANG_Chinese_PRC 0x0804 +#define FX_LANG_Chinese_Singapore 0x1004 +#define FX_LANG_Chinese_Taiwan 0x0404 +#define FX_LANG_Corsican_France 0x0483 +#define FX_LANG_Croatian_Croatia 0x041a +#define FX_LANG_Croatian_Latin 0x101a +#define FX_LANG_CustomCurrent 0x0c00 +#define FX_LANG_CzechRepublic 0x0405 +#define FX_LANG_Danish_Denmark 0x0406 +#define FX_LANG_Dari_Afghanistan 0x048c +#define FX_LANG_Divehi_Maldives 0x0465 +#define FX_LANG_Dutch_Belgium 0x0813 +#define FX_LANG_Dutch_Netherlands 0x0413 +#define FX_LANG_Dutch_Preferred 0x0013 +#define FX_LANG_Dzongkha 0x0851 +#define FX_LANG_Edo 0x0466 +#define FX_LANG_English_Australia 0x0c09 +#define FX_LANG_English_Belize 0x2809 +#define FX_LANG_English_Canada 0x1009 +#define FX_LANG_English_Caribbean 0x2409 +#define FX_LANG_English_HongKong 0x3c09 +#define FX_LANG_English_India 0x4009 +#define FX_LANG_English_Indonesia 0x3809 +#define FX_LANG_English_Ireland 0x1809 +#define FX_LANG_English_Jamaica 0x2009 +#define FX_LANG_English_Malaysia 0x4409 +#define FX_LANG_English_NewZealand 0x1409 +#define FX_LANG_English_Philippines 0x3409 +#define FX_LANG_English_Singapore 0x4809 +#define FX_LANG_English_SouthAfrica 0x1c09 +#define FX_LANG_English_TrinidadTobago 0x2c09 +#define FX_LANG_English_UnitedKingdom 0x0809 +#define FX_LANG_English_UnitedStates 0x0409 +#define FX_LANG_English_Zimbabwe 0x3009 +#define FX_LANG_Estonian_Estonia 0x0425 +#define FX_LANG_Faroese_FaroeIslands 0x0438 +#define FX_LANG_Filipino_Philippines 0x0464 +#define FX_LANG_Finnish_Finland 0x040b +#define FX_LANG_French_Belgium 0x080c +#define FX_LANG_French_Cameroon 0x2c0c +#define FX_LANG_French_Canada 0x0c0c +#define FX_LANG_French_CongoDRC 0x240c +#define FX_LANG_French_CotedIvoire 0x300c +#define FX_LANG_French_France 0x040c +#define FX_LANG_French_Haiti 0x3c0c +#define FX_LANG_French_Luxembourg 0x140c +#define FX_LANG_French_Mali 0x340c +#define FX_LANG_French_Monaco 0x180c +#define FX_LANG_French_Morocco 0x380c +#define FX_LANG_French_Reunion 0x200c +#define FX_LANG_French_Senegal 0x280c +#define FX_LANG_French_Switzerland 0x100c +#define FX_LANG_French_WestIndies 0x1c0c +#define FX_LANG_Frisian_Netherlands 0x0462 +#define FX_LANG_Fulfulde 0x0467 +#define FX_LANG_Gaelic_Ireland 0x083c +#define FX_LANG_Gaelic_Scotland 0x043c +#define FX_LANG_Galician_Galician 0x0456 +#define FX_LANG_Georgian_Georgia 0x0437 +#define FX_LANG_German_Austria 0x0c07 +#define FX_LANG_German_Germany 0x0407 +#define FX_LANG_German_Liechtenstein 0x1407 +#define FX_LANG_German_Luxembourg 0x1007 +#define FX_LANG_German_Switzerland 0x0807 +#define FX_LANG_Greek_Greece 0x0408 +#define FX_LANG_Greenlandic_Greenland 0x046f +#define FX_LANG_Guarani 0x0474 +#define FX_LANG_Gujarati_India 0x0447 +#define FX_LANG_Hausa_LatinNigeria 0x0468 +#define FX_LANG_Hawaiian 0x0475 +#define FX_LANG_Hebrew_Israel 0x040d +#define FX_LANG_Hindi_India 0x0439 +#define FX_LANG_Hungarian_Hungary 0x040e +#define FX_LANG_Ibibio_Nigeria 0x0469 +#define FX_LANG_Icelandic_Iceland 0x040f +#define FX_LANG_Igbo_Nigeria 0x0470 +#define FX_LANG_Indonesian_Indonesia 0x0421 +#define FX_LANG_Inuktitut_LatinCanada 0x085d +#define FX_LANG_Inuktitut_SyllabicsCanada 0x045d +#define FX_LANG_IsiXhosa_SouthAfrica 0x0434 +#define FX_LANG_IsiZulu_SouthAfrica 0x0435 +#define FX_LANG_Italian_Italy 0x0410 +#define FX_LANG_Italian_Switzerland 0x0810 +#define FX_LANG_Japanese_Japan 0x0411 +#define FX_LANG_Kannada_India 0x044b +#define FX_LANG_Kanuri 0x0471 +#define FX_LANG_Kashmiri 0x0860 +#define FX_LANG_Kashmiri_Arabic 0x0460 +#define FX_LANG_Kazakh_Kazakhstan 0x043f +#define FX_LANG_Khmer_Cambodia 0x0453 +#define FX_LANG_Kiche_Guatemala 0x0486 +#define FX_LANG_Kinyarwanda_Rwanda 0x0487 +#define FX_LANG_Kiswahili_Kenya 0x0441 +#define FX_LANG_Konkani_India 0x0457 +#define FX_LANG_Korean_Korea 0x0412 +#define FX_LANG_Kyrgyz_Kyrgyzstan 0x0440 +#define FX_LANG_Lao_LaoPDR 0x0454 +#define FX_LANG_Latin 0x0476 +#define FX_LANG_Latvian_Latvia 0x0426 +#define FX_LANG_Lithuanian_Lithuania 0x0427 +#define FX_LANG_LithuanianTrad 0x0827 +#define FX_LANG_Lower Sorbian_Germany 0x082e +#define FX_LANG_Luxembourgish_Luxembourg 0x046e +#define FX_LANG_Macedonian 0x042f +#define FX_LANG_Malay_BruneiDarussalam 0x083e +#define FX_LANG_Malay_Malaysia 0x043e +#define FX_LANG_Malayalam_India 0x044c +#define FX_LANG_Maldivian 0x0465 +#define FX_LANG_Maltese_Malta 0x043a +#define FX_LANG_Manipuri 0x0458 +#define FX_LANG_Maori_NewZealand 0x0481 +#define FX_LANG_Mapudungun_Chile 0x047a +#define FX_LANG_Marathi_India 0x044e +#define FX_LANG_Mohawk_Mohawk 0x047c +#define FX_LANG_Mongolian_CyrillicMongolia 0x0450 +#define FX_LANG_Mongolian_TraditionalMongolian 0x0850 +#define FX_LANG_Nepali_India 0x0861 +#define FX_LANG_Nepali_Nepal 0x0461 +#define FX_LANG_Norwegian_Bokmal 0x0414 +#define FX_LANG_Norwegian_Nynorsk 0x0814 +#define FX_LANG_Occitan_France 0x0482 +#define FX_LANG_Oriya_India 0x0448 +#define FX_LANG_Oromo 0x0472 +#define FX_LANG_Papiamentu 0x0479 +#define FX_LANG_Pashto_Afghanistan 0x0463 +#define FX_LANG_Persian 0x0429 +#define FX_LANG_Polish_Poland 0x0415 +#define FX_LANG_Portuguese_Brazil 0x0416 +#define FX_LANG_Portuguese_Portugal 0x0816 +#define FX_LANG_Punjabi_India 0x0446 +#define FX_LANG_Punjabi_Pakistan 0x0846 +#define FX_LANG_Quechua_Bolivia 0x046b +#define FX_LANG_Quechua_Ecuador 0x086b +#define FX_LANG_Quechua_Peru 0x0c6b +#define FX_LANG_Romanian_Moldova 0x0818 +#define FX_LANG_Romanian_Romania 0x0418 +#define FX_LANG_Romansh_Switzerland 0x0417 +#define FX_LANG_Russian_Moldova 0x0819 +#define FX_LANG_Russian_Russia 0x0419 +#define FX_LANG_Sami_InariFinland 0x243b +#define FX_LANG_Sami_LuleNorway 0x103b +#define FX_LANG_Sami_LuleSweden 0x143b +#define FX_LANG_Sami_NorthernFinland 0x0c3b +#define FX_LANG_Sami_NorthernNorway 0x043b +#define FX_LANG_Sami_NorthernSweden 0x083b +#define FX_LANG_Sami_SkoltFinland 0x203b +#define FX_LANG_Sami_SouthernNorway 0x183b +#define FX_LANG_Sami_SouthernSweden 0x1c3b +#define FX_LANG_SanskritIndia 0x044f +#define FX_LANG_SerbianCyrillic_BosniaHerzegovina 0x1c1a +#define FX_LANG_SerbianCyrillic_Serbia 0x0c1a +#define FX_LANG_SerbianLatin_BosniaHerzegovina 0x181a +#define FX_LANG_SerbianLatin_Serbia 0x081a +#define FX_LANG_SesothoSaLeboa 0x046c +#define FX_LANG_Setswana_SouthAfrica 0x0432 +#define FX_LANG_Sindhi_Arabic 0x0859 +#define FX_LANG_Sindhi_Devanagari 0x0459 +#define FX_LANG_Sinhala_SriLanka 0x045b +#define FX_LANG_Slovak_Slovakia 0x041b +#define FX_LANG_Slovenian_Slovenia 0x0424 +#define FX_LANG_Somali 0x0477 +#define FX_LANG_Spanish_Argentina 0x2c0a +#define FX_LANG_Spanish_Bolivia 0x400a +#define FX_LANG_Spanish_Chile 0x340a +#define FX_LANG_Spanish_Colombia 0x240a +#define FX_LANG_Spanish_CostaRica 0x140a +#define FX_LANG_Spanish_DominicanRepublic 0x1c0a +#define FX_LANG_Spanish_Ecuador 0x300a +#define FX_LANG_Spanish_ElSalvador 0x440a +#define FX_LANG_Spanish_Guatemala 0x100a +#define FX_LANG_Spanish_Honduras 0x480a +#define FX_LANG_Spanish_Mexico 0x080a +#define FX_LANG_Spanish_Nicaragua 0x4c0a +#define FX_LANG_Spanish_Panama 0x180a +#define FX_LANG_Spanish_Paraguay 0x3c0a +#define FX_LANG_Spanish_Peru 0x280a +#define FX_LANG_Spanish_PuertoRico 0x500a +#define FX_LANG_Spanish_InternationalSort 0x0c0a +#define FX_LANG_Spanish_TraditionalSort 0x040a +#define FX_LANG_Spanish_UnitedStates 0x540a +#define FX_LANG_Spanish_Uruguay 0x380a +#define FX_LANG_Spanish_Venezuela 0x200a +#define FX_LANG_Sutu_SouthAfrica 0x0430 +#define FX_LANG_Swedish_Finland 0x081d +#define FX_LANG_Swedish_Sweden 0x041d +#define FX_LANG_Syriac_Syria 0x045a +#define FX_LANG_Tajik_CyrillicTajikistan 0x0428 +#define FX_LANG_Tamazight_ArabicMorocco 0x045f +#define FX_LANG_Tamazight_LatinAlgeria 0x085f +#define FX_LANG_Tamil_India 0x0449 +#define FX_LANG_Tatar_Russia 0x0444 +#define FX_LANG_Telugu_India 0x044a +#define FX_LANG_Thai_Thailand 0x041e +#define FX_LANG_TibetanPRC 0x0451 +#define FX_LANG_Tigrigna_Eritrea 0x0873 +#define FX_LANG_Tigrigna_Ethiopia 0x0473 +#define FX_LANG_Tsonga 0x0431 +#define FX_LANG_Turkish_Turkey 0x041f +#define FX_LANG_Turkmen_Turkmenistan 0x0442 +#define FX_LANG_UighurPRC 0x0480 +#define FX_LANG_Ukrainian_Ukraine 0x0422 +#define FX_LANG_UpperSorbian_Germany 0x042e +#define FX_LANG_Urdu_Pakistan 0x0420 +#define FX_LANG_Urdu_India 0x0820 +#define FX_LANG_Uzbek_CyrillicUzbekistan 0x0843 +#define FX_LANG_Uzbek_LatinUzbekistan 0x0443 +#define FX_LANG_Venda 0x0433 +#define FX_LANG_Vietnamese_Vietnam 0x042a +#define FX_LANG_Welsh_UnitedKingdom 0x0452 +#define FX_LANG_Wolof_Senegal 0x0488 +#define FX_LANG_Xhosa 0x0434 +#define FX_LANG_Yakut_Russia 0x0485 +#define FX_LANG_YiPRC 0x0478 +#define FX_LANG_Yiddish 0x043d +#define FX_LANG_Yoruba_Nigeria 0x046a +#endif diff --git a/xfa/src/fgas/include/fx_locale.h b/xfa/src/fgas/include/fx_locale.h new file mode 100644 index 0000000000..6886974fd2 --- /dev/null +++ b/xfa/src/fgas/include/fx_locale.h @@ -0,0 +1,160 @@ +// 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_H_ +#define _FX_LOCALE_H_ +class CFX_Unitime; +class IFX_Locale; +class IFX_FormatString; +class IFX_LocaleMgr; +enum FX_LOCALENUMSYMBOL { + FX_LOCALENUMSYMBOL_Decimal, + FX_LOCALENUMSYMBOL_Grouping, + FX_LOCALENUMSYMBOL_Percent, + FX_LOCALENUMSYMBOL_Minus, + FX_LOCALENUMSYMBOL_Zero, + FX_LOCALENUMSYMBOL_CurrencySymbol, + FX_LOCALENUMSYMBOL_CurrencyName, +}; +enum FX_LOCALEDATETIMESUBCATEGORY { + FX_LOCALEDATETIMESUBCATEGORY_Default, + FX_LOCALEDATETIMESUBCATEGORY_Short, + FX_LOCALEDATETIMESUBCATEGORY_Medium, + FX_LOCALEDATETIMESUBCATEGORY_Full, + FX_LOCALEDATETIMESUBCATEGORY_Long, +}; +enum FX_LOCALENUMSUBCATEGORY { + FX_LOCALENUMPATTERN_Percent, + FX_LOCALENUMPATTERN_Currency, + FX_LOCALENUMPATTERN_Decimal, + FX_LOCALENUMPATTERN_Integer, +}; +enum FX_LOCALECATEGORY { + FX_LOCALECATEGORY_Unknown, + FX_LOCALECATEGORY_Date, + FX_LOCALECATEGORY_Time, + FX_LOCALECATEGORY_DateTime, + FX_LOCALECATEGORY_Num, + FX_LOCALECATEGORY_Text, + FX_LOCALECATEGORY_Zero, + FX_LOCALECATEGORY_Null, +}; +enum FX_DATETIMETYPE { + FX_DATETIMETYPE_Unknown, + FX_DATETIMETYPE_Date, + FX_DATETIMETYPE_Time, + FX_DATETIMETYPE_DateTime, + FX_DATETIMETYPE_TimeDate, +}; +class IFX_Locale +{ +public: + static IFX_Locale* Create(CXML_Element* pLocaleData); + + virtual void Release() = 0; + + + virtual CFX_WideString GetName() = 0; + + virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const = 0; + virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const = 0; + virtual void GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const = 0; + virtual void GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr = TRUE) const = 0; + virtual void GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM = TRUE) const = 0; + virtual void GetTimeZone(FX_TIMEZONE& tz) const = 0; + virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const = 0; + virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const = 0; + virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const = 0; + virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const = 0; +}; +class IFX_LocaleMgr +{ +public: + virtual void Release() = 0; + virtual FX_WORD GetDefLocaleID() = 0; + virtual IFX_Locale* GetDefLocale() = 0; + virtual IFX_Locale* GetLocale(FX_WORD lcid) = 0; + virtual IFX_Locale* GetLocaleByName(FX_WSTR wsLocaleName) = 0; +}; +IFX_LocaleMgr* FX_LocaleMgr_Create(FX_LPCWSTR pszLocalPath, FX_WORD wDefaultLCID); +void FX_ParseNumString(const CFX_WideString& wsNum, CFX_WideString& wsResult); +FX_BOOL FX_DateFromCanonical(const CFX_WideString& wsDate, CFX_Unitime& datetime); +FX_BOOL FX_TimeFromCanonical(FX_WSTR wsTime, CFX_Unitime& datetime, IFX_Locale* pLocale); +class IFX_FormatString +{ +public: + static IFX_FormatString* Create(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID); + + virtual void Release() = 0; + virtual void SplitFormatString(const CFX_WideString& wsFormatString, CFX_WideStringArray& wsPatterns) = 0; + virtual FX_LOCALECATEGORY GetCategory(const CFX_WideString& wsPattern) = 0; + virtual FX_WORD GetLCID(const CFX_WideString& wsPattern) = 0; + virtual CFX_WideString GetLocaleName(const CFX_WideString& wsPattern) = 0; + virtual FX_BOOL ParseText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsValue) = 0; + virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, FX_FLOAT &fValue) = 0; + virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString &wsValue) = 0; + virtual FX_BOOL ParseDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, FX_DATETIMETYPE eDateTimeType, CFX_Unitime& dtValue) = 0; + virtual FX_BOOL ParseZero(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) = 0; + virtual FX_BOOL ParseNull(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) = 0; + virtual FX_BOOL FormatText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatNum(FX_FLOAT fNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput, FX_DATETIMETYPE eDateTimeType) = 0; + virtual FX_BOOL FormatDateTime(const CFX_Unitime& dt, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatZero(const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; + virtual FX_BOOL FormatNull(const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0; +}; +class CFX_Decimal : CFX_Object +{ +public: + CFX_Decimal(); + CFX_Decimal(FX_UINT32 val); + CFX_Decimal(FX_UINT64 val); + CFX_Decimal(FX_INT32 val); + CFX_Decimal(FX_INT64 val); + CFX_Decimal(FX_FLOAT val, FX_UINT8 scale = 3); + CFX_Decimal(FX_WSTR str); + CFX_Decimal(FX_BSTR str); + operator CFX_WideString() const; + operator double() const; + FX_BOOL operator == (const CFX_Decimal& val) const; + FX_BOOL operator <= (const CFX_Decimal& val) const; + FX_BOOL operator >= (const CFX_Decimal& val) const; + FX_BOOL operator != (const CFX_Decimal& val) const; + FX_BOOL operator < (const CFX_Decimal& val) const; + FX_BOOL operator > (const CFX_Decimal& val) const; + CFX_Decimal operator + (const CFX_Decimal& val) const; + CFX_Decimal operator - (const CFX_Decimal& val) const; + CFX_Decimal operator * (const CFX_Decimal& val) const; + CFX_Decimal operator / (const CFX_Decimal& val) const; + CFX_Decimal operator % (const CFX_Decimal& val) const; + void SetScale(FX_UINT8 newScale); + FX_UINT8 GetScale(); + void SetAbs(); + void SetNegate(); + void SetFloor(); + void SetCeiling(); + void SetTruncate(); +protected: + CFX_Decimal(FX_UINT32 hi, FX_UINT32 mid, FX_UINT32 lo, FX_BOOL neg, FX_UINT8 scale); + inline FX_BOOL IsNotZero() const + { + return m_uHi || m_uMid || m_uLo; + } + inline FX_INT8 Compare (const CFX_Decimal& val) const; + inline void Swap(CFX_Decimal& val); + inline void FloorOrCeil(FX_BOOL bFloor); + CFX_Decimal AddOrMinus(const CFX_Decimal& val, FX_BOOL isAdding) const; + CFX_Decimal Multiply(const CFX_Decimal& val) const; + CFX_Decimal Divide(const CFX_Decimal& val) const; + CFX_Decimal Modulus(const CFX_Decimal& val) const; + FX_UINT32 m_uFlags; + FX_UINT32 m_uHi; + FX_UINT32 m_uLo; + FX_UINT32 m_uMid; +}; +#endif diff --git a/xfa/src/fgas/include/fx_mem.h b/xfa/src/fgas/include/fx_mem.h new file mode 100644 index 0000000000..18cd85e422 --- /dev/null +++ b/xfa/src/fgas/include/fx_mem.h @@ -0,0 +1,58 @@ +// 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 +#define _FX_MEMORY +class IFX_MEMAllocator; +class CFX_Target; +enum FX_ALLOCTYPE { + FX_ALLOCTYPE_Default = 0, + FX_ALLOCTYPE_Static , + FX_ALLOCTYPE_Fixed , + FX_ALLOCTYPE_Dynamic , +}; +class IFX_MEMAllocator +{ +public: + virtual void Release() = 0; + virtual void* Alloc(size_t size) = 0; + virtual void Free(void *pBlock) = 0; + virtual size_t GetBlockSize() const = 0; + virtual size_t GetDefChunkSize() const = 0; + virtual size_t SetDefChunkSize(size_t size) = 0; + virtual size_t GetCurrentDataSize() const = 0; +}; +IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType, size_t chunkSize, size_t blockSize); +class CFX_Target +{ +public: + void* operator new(size_t size) + { + return FX_Alloc(FX_BYTE, size); + } + void operator delete(void *p) + { + FX_Free(p); + } + void* operator new(size_t size, IFX_MEMAllocator *pAllocator) + { + return pAllocator->Alloc(size); + } + void operator delete(void *p, IFX_MEMAllocator *pAllocator) + { + pAllocator->Free(p); + } + void* operator new(size_t size, void *place) + { + return place; + } + void operator delete(void *p, void *place) {} +}; +#define FXTARGET_New new +#define FXTARGET_NewWith(__allocator__) new(__allocator__) +#define FXTARGET_Delete delete +#define FXTARGET_DeleteWith(__class__, __allocator__, pointer) {(pointer)->~__class__(); (pointer)->operator delete((pointer), (__allocator__));} +#endif diff --git a/xfa/src/fgas/include/fx_rbk.h b/xfa/src/fgas/include/fx_rbk.h new file mode 100644 index 0000000000..3053fc5e1b --- /dev/null +++ b/xfa/src/fgas/include/fx_rbk.h @@ -0,0 +1,235 @@ +// 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 +#define _FX_RTFBREAK +class IFX_Unknown; +class IFX_Font; +class CFX_Char; +class CFX_RTFChar; +class CFX_RTFBreakPiece; +class IFX_RTFBreak; +#define FX_RTFBREAKPOLICY_None 0x00 +#define FX_RTFBREAKPOLICY_SpaceBreak 0x01 +#define FX_RTFBREAKPOLICY_NumberBreak 0x02 +#define FX_RTFBREAKPOLICY_InfixBreak 0x04 +#define FX_RTFBREAKPOLICY_TabBreak 0x08 +#define FX_RTFBREAKPOLICY_OrphanPositionedTab 0x10 +#define FX_RTFBREAK_None 0x00 +#define FX_RTFBREAK_PieceBreak 0x01 +#define FX_RTFBREAK_LineBreak 0x02 +#define FX_RTFBREAK_ParagraphBreak 0x03 +#define FX_RTFBREAK_PageBreak 0x04 +#define FX_RTFLAYOUTSTYLE_Pagination 0x01 +#define FX_RTFLAYOUTSTYLE_VerticalLayout 0x02 +#define FX_RTFLAYOUTSTYLE_VerticalChars 0x04 +#define FX_RTFLAYOUTSTYLE_LineDirection 0x08 +#define FX_RTFLAYOUTSTYLE_ExpandTab 0x10 +#define FX_RTFLAYOUTSTYLE_ArabicNumber 0x20 +#define FX_RTFLAYOUTSTYLE_SingleLine 0x40 +#define FX_RTFLAYOUTSTYLE_MBCSCode 0x80 +#define FX_RTFCHARSTYLE_Alignment 0x000F +#define FX_RTFCHARSTYLE_ArabicNumber 0x0010 +#define FX_RTFCHARSTYLE_ArabicShadda 0x0020 +#define FX_RTFCHARSTYLE_OddBidiLevel 0x0040 +#define FX_RTFCHARSTYLE_RTLReadingOrder 0x0080 +#define FX_RTFCHARSTYLE_ArabicContext 0x0300 +#define FX_RTFCHARSTYLE_ArabicIndic 0x0400 +#define FX_RTFCHARSTYLE_ArabicComma 0x0800 +#define FX_RTFLINEALIGNMENT_Left 0 +#define FX_RTFLINEALIGNMENT_Center 1 +#define FX_RTFLINEALIGNMENT_Right 2 +#define FX_RTFLINEALIGNMENT_Justified (1 << 2) +#define FX_RTFLINEALIGNMENT_Distributed (2 << 2) +#define FX_RTFLINEALIGNMENT_JustifiedLeft (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Justified) +#define FX_RTFLINEALIGNMENT_JustifiedCenter (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Justified) +#define FX_RTFLINEALIGNMENT_JustifiedRight (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Justified) +#define FX_RTFLINEALIGNMENT_DistributedLeft (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Distributed) +#define FX_RTFLINEALIGNMENT_DistributedCenter (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Distributed) +#define FX_RTFLINEALIGNMENT_DistributedRight (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Distributed) +#define FX_RTFLINEALIGNMENT_LowerMask 0x03 +#define FX_RTFLINEALIGNMENT_HigherMask 0x0C +typedef struct _FX_RTFTEXTOBJ { + _FX_RTFTEXTOBJ() + { + pStr = NULL; + pWidths = NULL; + iLength = 0; + pFont = NULL; + fFontSize = 12.0f; + dwLayoutStyles = 0; + iCharRotation = 0; + iBidiLevel = 0; + pRect = NULL; + wLineBreakChar = L'\n'; + iHorizontalScale = 100; + iVerticalScale = 100; + } + FX_LPCWSTR pStr; + FX_INT32 *pWidths; + FX_INT32 iLength; + IFX_Font *pFont; + FX_FLOAT fFontSize; + FX_DWORD dwLayoutStyles; + FX_INT32 iCharRotation; + FX_INT32 iBidiLevel; + FX_LPCRECTF pRect; + FX_WCHAR wLineBreakChar; + FX_INT32 iHorizontalScale; + FX_INT32 iVerticalScale; +} FX_RTFTEXTOBJ, * FX_LPRTFTEXTOBJ; +typedef FX_RTFTEXTOBJ const * FX_LPCRTFTEXTOBJ; +class CFX_RTFPiece : public CFX_Target +{ +public: + CFX_RTFPiece() : m_dwStatus(FX_RTFBREAK_PieceBreak) + , m_iStartPos(0) + , m_iWidth(-1) + , m_iStartChar(0) + , m_iChars(0) + , m_iBidiLevel(0) + , m_iBidiPos(0) + , m_iFontSize(0) + , m_iFontHeight(0) + , m_iHorizontalScale(100) + , m_iVerticalScale(100) + , m_dwLayoutStyles(0) + , m_dwIdentity(0) + , m_pChars(NULL) + , m_pUserData(NULL) + { + } + ~CFX_RTFPiece() + { + Reset(); + } + void AppendChar(const CFX_RTFChar &tc) + { + FXSYS_assert(m_pChars != NULL); + m_pChars->Add(tc); + if (m_iWidth < 0) { + m_iWidth = tc.m_iCharWidth; + } else { + m_iWidth += tc.m_iCharWidth; + } + m_iChars ++; + } + FX_INT32 GetEndPos() const + { + return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth; + } + FX_INT32 GetLength() const + { + return m_iChars; + } + FX_INT32 GetEndChar() const + { + return m_iStartChar + m_iChars; + } + CFX_RTFChar& GetChar(FX_INT32 index) + { + FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL); + return *m_pChars->GetDataPtr(m_iStartChar + index); + } + CFX_RTFChar* GetCharPtr(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL); + return m_pChars->GetDataPtr(m_iStartChar + index); + } + void GetString (FX_LPWSTR pText) const + { + FXSYS_assert(pText != NULL); + FX_INT32 iEndChar = m_iStartChar + m_iChars; + CFX_RTFChar *pChar; + for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) { + pChar = m_pChars->GetDataPtr(i); + *pText ++ = (FX_WCHAR)pChar->m_wCharCode; + } + } + void GetString(CFX_WideString &wsText) const + { + FX_LPWSTR pText = wsText.GetBuffer(m_iChars); + GetString(pText); + wsText.ReleaseBuffer(m_iChars); + } + void GetWidths(FX_INT32 *pWidths) const + { + FXSYS_assert(pWidths != NULL); + FX_INT32 iEndChar = m_iStartChar + m_iChars; + CFX_RTFChar *pChar; + for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) { + pChar = m_pChars->GetDataPtr(i); + *pWidths ++ = pChar->m_iCharWidth; + } + } + void Reset() + { + m_dwStatus = FX_RTFBREAK_PieceBreak; + if (m_iWidth > -1) { + m_iStartPos += m_iWidth; + } + m_iWidth = -1; + m_iStartChar += m_iChars; + m_iChars = 0; + m_iBidiLevel = 0; + m_iBidiPos = 0; + m_iHorizontalScale = 100; + m_iVerticalScale = 100; + } + FX_DWORD m_dwStatus; + FX_INT32 m_iStartPos; + FX_INT32 m_iWidth; + FX_INT32 m_iStartChar; + FX_INT32 m_iChars; + FX_INT32 m_iBidiLevel; + FX_INT32 m_iBidiPos; + FX_INT32 m_iFontSize; + FX_INT32 m_iFontHeight; + FX_INT32 m_iHorizontalScale; + FX_INT32 m_iVerticalScale; + FX_DWORD m_dwLayoutStyles; + FX_DWORD m_dwIdentity; + CFX_RTFCharArray *m_pChars; + IFX_Unknown *m_pUserData; +}; +typedef CFX_BaseArrayTemplate CFX_RTFPieceArray; +class IFX_RTFBreak +{ +public: + static IFX_RTFBreak* Create(FX_DWORD dwPolicies); + virtual void Release() = 0; + virtual void SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) = 0; + virtual void SetLinePos(FX_FLOAT fLinePos) = 0; + virtual FX_DWORD GetLayoutStyles() const = 0; + virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles) = 0; + virtual void SetFont(IFX_Font *pFont) = 0; + virtual void SetFontSize(FX_FLOAT fFontSize) = 0; + virtual void SetTabWidth(FX_FLOAT fTabWidth) = 0; + virtual void AddPositionedTab(FX_FLOAT fTabPos) = 0; + virtual void SetPositionedTabs(const CFX_FloatArray &tabs) = 0; + virtual void ClearPositionedTabs() = 0; + virtual void SetDefaultChar(FX_WCHAR wch) = 0; + virtual void SetLineBreakChar(FX_WCHAR wch) = 0; + virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0; + virtual void SetHorizontalScale(FX_INT32 iScale) = 0; + virtual void SetVerticalScale(FX_INT32 iScale) = 0; + virtual void SetCharRotation(FX_INT32 iCharRotation) = 0; + virtual void SetCharSpace(FX_FLOAT fCharSpace) = 0; + virtual void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) = 0; + virtual void SetReadingOrder(FX_BOOL bRTL = FALSE) = 0; + virtual void SetAlignment(FX_INT32 iAlignment = FX_RTFLINEALIGNMENT_Left) = 0; + virtual void SetUserData(IFX_Unknown *pUserData) = 0; + virtual FX_DWORD AppendChar(FX_WCHAR wch) = 0; + virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak) = 0; + virtual FX_INT32 CountBreakPieces() const = 0; + virtual const CFX_RTFPiece* GetBreakPiece(FX_INT32 index) const = 0; + virtual void GetLineRect(CFX_RectF &rect) const = 0; + virtual void ClearBreakPieces() = 0; + virtual void Reset() = 0; + virtual FX_INT32 GetDisplayPos(FX_LPCRTFTEXTOBJ pText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const = 0; + virtual FX_INT32 GetCharRects(FX_LPCRTFTEXTOBJ pText, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const = 0; +}; +#endif diff --git a/xfa/src/fgas/include/fx_sax.h b/xfa/src/fgas/include/fx_sax.h new file mode 100644 index 0000000000..c0159f8c22 --- /dev/null +++ b/xfa/src/fgas/include/fx_sax.h @@ -0,0 +1,48 @@ +// 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_ +#define _FX_SAX_ +class IFX_SAXReaderHandler; +class IFX_SAXReader; +#define FX_SAXPARSEMODE_NotConvert_amp 0x0001 +#define FX_SAXPARSEMODE_NotConvert_lt 0x0002 +#define FX_SAXPARSEMODE_NotConvert_gt 0x0004 +#define FX_SAXPARSEMODE_NotConvert_apos 0x0008 +#define FX_SAXPARSEMODE_NotConvert_quot 0x0010 +#define FX_SAXPARSEMODE_NotConvert_sharp 0x0020 +#define FX_SAXPARSEMODE_NotSkipSpace 0x0100 +enum FX_SAXNODE { + FX_SAXNODE_Unknown = 0, + FX_SAXNODE_Instruction, + FX_SAXNODE_Declaration, + FX_SAXNODE_Comment, + FX_SAXNODE_Tag, + FX_SAXNODE_Text, + FX_SAXNODE_CharData, +}; +class IFX_SAXReaderHandler +{ +public: + virtual FX_LPVOID OnTagEnter(FX_BSTR bsTagName, FX_SAXNODE eType, FX_DWORD dwStartPos) = 0; + virtual void OnTagAttribute(FX_LPVOID pTag, FX_BSTR bsAttri, FX_BSTR bsValue) = 0; + virtual void OnTagBreak(FX_LPVOID pTag) = 0; + virtual void OnTagData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos) = 0; + virtual void OnTagClose(FX_LPVOID pTag, FX_DWORD dwEndPos) = 0; + virtual void OnTagEnd(FX_LPVOID pTag, FX_BSTR bsTagName, FX_DWORD dwEndPos) = 0; + virtual void OnTargetData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos) = 0; +}; +class IFX_SAXReader +{ +public: + virtual void Release() = 0; + virtual FX_INT32 StartParse(IFX_FileRead *pFile, FX_DWORD dwStart = 0, FX_DWORD dwLen = -1, FX_DWORD dwParseMode = 0) = 0; + virtual FX_INT32 ContinueParse(IFX_Pause *pPause = NULL) = 0; + virtual void SkipCurrentNode() = 0; + virtual void SetHandler(IFX_SAXReaderHandler *pHandler) = 0; +}; +IFX_SAXReader* FX_SAXReader_Create(); +#endif diff --git a/xfa/src/fgas/include/fx_stm.h b/xfa/src/fgas/include/fx_stm.h new file mode 100644 index 0000000000..ae424dba2d --- /dev/null +++ b/xfa/src/fgas/include/fx_stm.h @@ -0,0 +1,60 @@ +// 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 +#define _FX_STREAM +class IFX_Stream; +IFX_FileRead* FX_CreateFileRead(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream = FALSE); +#ifdef FX_FILESIZE +IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize = -1, FX_BOOL bReleaseStream = TRUE); +#else +IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize = -1, FX_BOOL bReleaseStream = TRUE); +#endif +IFX_FileWrite* FX_CreateFileWrite(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream = FALSE); +enum FX_STREAMACCESS { + FX_STREAMACCESS_Binary = 0x00, + FX_STREAMACCESS_Text = 0x01, + FX_STREAMACCESS_Read = 0x02, + FX_STREAMACCESS_Write = 0x04, + FX_STREAMACCESS_Truncate = 0x10, + FX_STREAMACCESS_Append = 0x20, + FX_STREAMACCESS_Create = 0x80, +}; +enum FX_STREAMSEEK { + FX_STREAMSEEK_Begin = 0 , + FX_STREAMSEEK_Current , + FX_STREAMSEEK_End , +}; +class IFX_Stream +{ +public: + static IFX_Stream* CreateStream(IFX_FileRead *pFileRead, FX_DWORD dwAccess); + static IFX_Stream* CreateStream(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess); + static IFX_Stream* CreateStream(FX_LPCWSTR pszFileName, FX_DWORD dwAccess); + static IFX_Stream* CreateStream(FX_LPBYTE pData, FX_INT32 length, FX_DWORD dwAccess); + static IFX_Stream* CreateStream(IFX_BufferRead *pBufferRead, FX_DWORD dwAccess, FX_INT32 iFileSize = -1, FX_BOOL bReleaseBufferRead = TRUE); + static IFX_Stream* CreateTextStream(IFX_Stream *pBaseStream, FX_BOOL bDeleteOnRelease); + virtual void Release() = 0; + virtual IFX_Stream* Retain() = 0; + virtual FX_DWORD GetAccessModes() const = 0; + virtual FX_INT32 GetLength() const = 0; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) = 0; + virtual FX_INT32 GetPosition() = 0; + virtual FX_BOOL IsEOF() const = 0; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) = 0; + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL) = 0; + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) = 0; + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) = 0; + virtual void Flush() = 0; + virtual FX_BOOL SetLength(FX_INT32 iLength) = 0; + virtual FX_INT32 GetBOM(FX_BYTE bom[4]) const = 0; + virtual FX_WORD GetCodePage() const = 0; + virtual FX_WORD SetCodePage(FX_WORD wCodePage) = 0; + virtual void Lock() = 0; + virtual void Unlock() = 0; + virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength) = 0; +}; +#endif diff --git a/xfa/src/fgas/include/fx_sys.h b/xfa/src/fgas/include/fx_sys.h new file mode 100644 index 0000000000..c0b5c7445f --- /dev/null +++ b/xfa/src/fgas/include/fx_sys.h @@ -0,0 +1,63 @@ +// 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_SYSTEM +#define _FX_SYSTEM +#ifdef __cplusplus +extern "C" { +#endif +#define FX_RAD2DEG(r) ((r) * 180.0f / FX_PI) +#define FX_DEG2RAD(a) ((a) * FX_PI / 180.0f) +typedef FX_INT8 * FX_LPINT8; +typedef FX_INT8 const * FX_LPCINT8; +typedef FX_INT32 * FX_LPINT32; +typedef FX_INT32 const * FX_LPCINT32; +typedef long FX_LONG; +typedef FX_LONG * FX_LPLONG; +typedef FX_LONG const * FX_LPCLONG; +typedef FX_FLOAT const * FX_LPCFLOAT; +typedef double FX_DOUBLE; +typedef FX_DOUBLE * FX_LPDOUBLE; +typedef FX_DOUBLE const * FX_LPCDOUBLE; +FX_FLOAT FX_tan(FX_FLOAT a); +FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x); +FX_FLOAT FX_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength = -1, FX_INT32 *pUsedLen = NULL); +FX_FLOAT FX_wcstof(FX_LPCWSTR pwsStr, FX_INT32 iLength = -1, FX_INT32 *pUsedLen = NULL); +FX_LPWSTR FX_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR srcStr, size_t count); +FX_INT32 FX_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR s2, size_t count); +FX_INT32 FX_strnicmp(FX_LPCSTR s1, FX_LPCSTR s2, size_t count); +inline FX_BOOL FX_islower(FX_INT32 ch) +{ + return ch >= 'a' && ch <= 'z'; +} +inline FX_BOOL FX_isupper(FX_INT32 ch) +{ + return ch >= 'A' && ch <= 'Z'; +} +inline FX_INT32 FX_tolower(FX_INT32 ch) +{ + return FX_isupper(ch) ? (ch + 0x20) : ch; +} +inline FX_INT32 FX_toupper(FX_INT32 ch) +{ + return FX_islower(ch) ? (ch - 0x20) : ch; +} +FX_INT32 FX_filelength(FXSYS_FILE *file); +FX_BOOL FX_fsetsize(FXSYS_FILE *file, FX_INT32 size); +void FX_memset(FX_LPVOID pBuf, FX_INT32 iValue, size_t size); +void FX_memcpy(FX_LPVOID pDst, FX_LPCVOID pSrc, size_t size); +FX_BOOL FX_IsRelativePath(const CFX_WideStringC &wsPath); +FX_BOOL FX_JoinPath(const CFX_WideStringC &wsBasePath, const CFX_WideStringC &wsRelativePath, CFX_WideString &wsAbsolutePath); +typedef struct _FX_VERSION { + FX_DWORD dwMajorVersion; + FX_DWORD dwMinorVersion; + FX_DWORD dwBuildVersion; +} FX_VERSION, * FX_LPVERSION; +typedef FX_VERSION const * FX_LPCVERSION; +#ifdef __cplusplus +}; +#endif +#endif diff --git a/xfa/src/fgas/include/fx_tbk.h b/xfa/src/fgas/include/fx_tbk.h new file mode 100644 index 0000000000..ab64d1dac0 --- /dev/null +++ b/xfa/src/fgas/include/fx_tbk.h @@ -0,0 +1,211 @@ +// 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 +#define _FX_TEXTBREAK +class IFX_Font; +class CFX_Char; +class IFX_TxtAccess; +class CFX_TxtChar; +class CFX_TxtPiece; +class IFX_TxtBreak; +#define FX_TXTBREAKPOLICY_None 0x00 +#define FX_TXTBREAKPOLICY_Pagination 0x01 +#define FX_TXTBREAKPOLICY_SpaceBreak 0x02 +#define FX_TXTBREAKPOLICY_NumberBreak 0x04 +#define FX_TXTBREAK_None 0x00 +#define FX_TXTBREAK_PieceBreak 0x01 +#define FX_TXTBREAK_LineBreak 0x02 +#define FX_TXTBREAK_ParagraphBreak 0x03 +#define FX_TXTBREAK_PageBreak 0x04 +#define FX_TXTBREAK_ControlChar 0x10 +#define FX_TXTBREAK_BreakChar 0x20 +#define FX_TXTBREAK_UnknownChar 0x40 +#define FX_TXTBREAK_RemoveChar 0x80 +#define FX_TXTLAYOUTSTYLE_MutipleFormat 0x0001 +#define FX_TXTLAYOUTSTYLE_VerticalLayout 0x0002 +#define FX_TXTLAYOUTSTYLE_VerticalChars 0x0004 +#define FX_TXTLAYOUTSTYLE_ReverseLine 0x0008 +#define FX_TXTLAYOUTSTYLE_ArabicContext 0x0010 +#define FX_TXTLAYOUTSTYLE_ArabicShapes 0x0020 +#define FX_TXTLAYOUTSTYLE_RTLReadingOrder 0x0040 +#define FX_TXTLAYOUTSTYLE_ExpandTab 0x0100 +#define FX_TXTLAYOUTSTYLE_SingleLine 0x0200 +#define FX_TXTLAYOUTSTYLE_CombText 0x0400 +#define FX_TXTCHARSTYLE_Alignment 0x000F +#define FX_TXTCHARSTYLE_ArabicNumber 0x0010 +#define FX_TXTCHARSTYLE_ArabicShadda 0x0020 +#define FX_TXTCHARSTYLE_OddBidiLevel 0x0040 +#define FX_TXTCHARSTYLE_RTLReadingOrder 0x0080 +#define FX_TXTCHARSTYLE_ArabicContext 0x0300 +#define FX_TXTCHARSTYLE_ArabicIndic 0x0400 +#define FX_TXTCHARSTYLE_ArabicComma 0x0800 +#define FX_TXTLINEALIGNMENT_Left 0 +#define FX_TXTLINEALIGNMENT_Center 1 +#define FX_TXTLINEALIGNMENT_Right 2 +#define FX_TXTLINEALIGNMENT_Justified (1 << 2) +#define FX_TXTLINEALIGNMENT_Distributed (2 << 2) +#define FX_TXTLINEALIGNMENT_JustifiedLeft (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Justified) +#define FX_TXTLINEALIGNMENT_JustifiedCenter (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Justified) +#define FX_TXTLINEALIGNMENT_JustifiedRight (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Justified) +#define FX_TXTLINEALIGNMENT_DistributedLeft (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Distributed) +#define FX_TXTLINEALIGNMENT_DistributedCenter (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Distributed) +#define FX_TXTLINEALIGNMENT_DistributedRight (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Distributed) +#define FX_TXTLINEALIGNMENT_LowerMask 0x03 +#define FX_TXTLINEALIGNMENT_HigherMask 0x0C +#define FX_TXTBREAK_MinimumTabWidth 160000 +class IFX_TxtAccess +{ +public: + virtual FX_WCHAR GetChar(FX_LPVOID pIdentity, FX_INT32 index) const = 0; + virtual FX_INT32 GetWidth(FX_LPVOID pIdentity, FX_INT32 index) const = 0; +}; +typedef struct _FX_TXTRUN { + _FX_TXTRUN() + { + pAccess = NULL; + pIdentity = NULL; + pStr = NULL; + pWidths = NULL; + iLength = 0; + pFont = NULL; + fFontSize = 12; + dwStyles = 0; + iHorizontalScale = 100; + iVerticalScale = 100; + iCharRotation = 0; + dwCharStyles = 0; + pRect = NULL; + wLineBreakChar = L'\n'; + bSkipSpace = TRUE; + } + IFX_TxtAccess *pAccess; + FX_LPVOID pIdentity; + FX_LPCWSTR pStr; + FX_INT32 *pWidths; + FX_INT32 iLength; + IFX_Font *pFont; + FX_FLOAT fFontSize; + FX_DWORD dwStyles; + FX_INT32 iHorizontalScale; + FX_INT32 iVerticalScale; + FX_INT32 iCharRotation; + FX_DWORD dwCharStyles; + FX_LPCRECTF pRect; + FX_WCHAR wLineBreakChar; + FX_BOOL bSkipSpace; +} FX_TXTRUN, * FX_LPTXTRUN; +typedef FX_TXTRUN const * FX_LPCTXTRUN; +class CFX_TxtPiece : public CFX_Target +{ +public: + CFX_TxtPiece() : m_dwStatus(FX_TXTBREAK_PieceBreak) + , m_iStartPos(0) + , m_iWidth(-1) + , m_iStartChar(0) + , m_iChars(0) + , m_iBidiLevel(0) + , m_iBidiPos(0) + , m_iHorizontalScale(100) + , m_iVerticalScale(100) + , m_dwCharStyles(0) + , m_pChars(NULL) + , m_pUserData(NULL) + { + } + FX_INT32 GetEndPos() const + { + return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth; + } + FX_INT32 GetLength() const + { + return m_iChars; + } + FX_INT32 GetEndChar() const + { + return m_iStartChar + m_iChars; + } + CFX_TxtChar* GetCharPtr(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL); + return m_pChars->GetDataPtr(m_iStartChar + index); + } + void GetString(FX_LPWSTR pText) const + { + FXSYS_assert(pText != NULL); + FX_INT32 iEndChar = m_iStartChar + m_iChars; + CFX_Char *pChar; + for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) { + pChar = m_pChars->GetDataPtr(i); + *pText ++ = (FX_WCHAR)pChar->m_wCharCode; + } + } + + void GetString(CFX_WideString &wsText) const + { + FX_LPWSTR pText = wsText.GetBuffer(m_iChars); + GetString(pText); + wsText.ReleaseBuffer(m_iChars); + } + void GetWidths(FX_INT32 *pWidths) const + { + FXSYS_assert(pWidths != NULL); + FX_INT32 iEndChar = m_iStartChar + m_iChars; + CFX_Char *pChar; + for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) { + pChar = m_pChars->GetDataPtr(i); + *pWidths ++ = pChar->m_iCharWidth; + } + } + FX_DWORD m_dwStatus; + FX_INT32 m_iStartPos; + FX_INT32 m_iWidth; + FX_INT32 m_iStartChar; + FX_INT32 m_iChars; + FX_INT32 m_iBidiLevel; + FX_INT32 m_iBidiPos; + FX_INT32 m_iHorizontalScale; + FX_INT32 m_iVerticalScale; + FX_DWORD m_dwCharStyles; + CFX_TxtCharArray *m_pChars; + FX_LPVOID m_pUserData; +}; +typedef CFX_BaseArrayTemplate CFX_TxtPieceArray; +class IFX_TxtBreak +{ +public: + static IFX_TxtBreak* Create(FX_DWORD dwPolicies); + virtual void Release() = 0; + virtual void SetLineWidth(FX_FLOAT fLineWidth) = 0; + virtual void SetLinePos(FX_FLOAT fLinePos) = 0; + virtual FX_DWORD GetLayoutStyles() const = 0; + virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles) = 0; + virtual void SetFont(IFX_Font *pFont) = 0; + virtual void SetFontSize(FX_FLOAT fFontSize) = 0; + virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) = 0; + virtual void SetDefaultChar(FX_WCHAR wch) = 0; + virtual void SetParagraphBreakChar(FX_WCHAR wch) = 0; + virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0; + virtual void SetHorizontalScale(FX_INT32 iScale) = 0; + virtual void SetVerticalScale(FX_INT32 iScale) = 0; + virtual void SetCharRotation(FX_INT32 iCharRotation) = 0; + virtual void SetCharSpace(FX_FLOAT fCharSpace) = 0; + virtual void SetAlignment(FX_INT32 iAlignment) = 0; + virtual FX_DWORD GetContextCharStyles() const = 0; + virtual void SetContextCharStyles(FX_DWORD dwCharStyles) = 0; + virtual void SetCombWidth(FX_FLOAT fCombWidth) = 0; + virtual void SetUserData(FX_LPVOID pUserData) = 0; + virtual FX_DWORD AppendChar(FX_WCHAR wch) = 0; + virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak) = 0; + virtual FX_INT32 CountBreakChars() const = 0; + virtual FX_INT32 CountBreakPieces() const = 0; + virtual const CFX_TxtPiece* GetBreakPiece(FX_INT32 index) const = 0; + virtual void ClearBreakPieces() = 0; + virtual void Reset() = 0; + virtual FX_INT32 GetDisplayPos(FX_LPCTXTRUN pTxtRun, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const = 0; + virtual FX_INT32 GetCharRects(FX_LPCTXTRUN pTxtRun, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const = 0; +}; +#endif diff --git a/xfa/src/fgas/include/fx_ucd.h b/xfa/src/fgas/include/fx_ucd.h new file mode 100644 index 0000000000..715c8af4dd --- /dev/null +++ b/xfa/src/fgas/include/fx_ucd.h @@ -0,0 +1,23 @@ +// 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_ +#define _FGAS_UNICODE_ +#define FX_JAPCHARPROPERTYEX_Left 0x01 +#define FX_JAPCHARPROPERTYEX_Center 0x02 +#define FX_JAPCHARPROPERTYEX_Right 0x03 +#define FX_JAPCHARPROPERTYEX_Top 0x10 +#define FX_JAPCHARPROPERTYEX_Middle 0x20 +#define FX_JAPCHARPROPERTYEX_Bottom 0x30 +typedef struct _FX_JAPCHARPROPERTYEX { + FX_WCHAR wChar; + FX_BYTE uAlign; +} FX_JAPCHARPROPERTYEX, *FX_LPJAPCHARPROPERTYEX; +typedef FX_JAPCHARPROPERTYEX const * FX_LPCJAPCHARPROPERTYEX; +FX_LPCJAPCHARPROPERTYEX FX_GetJapCharPropertyEx(FX_WCHAR wch); +typedef FX_BOOL (*FX_AdjustCharDisplayPos)(FX_WCHAR wch, FX_BOOL bMBCSCode, IFX_Font *pFont, FX_FLOAT fFontSize, FX_BOOL bVertical, CFX_PointF &ptOffset); +FX_BOOL FX_AdjustJapCharDisplayPos(FX_WCHAR wch, FX_BOOL bMBCSCode, IFX_Font *pFont, FX_FLOAT fFontSize, FX_BOOL bVertical, CFX_PointF &ptOffset); +#endif diff --git a/xfa/src/fgas/include/fx_utl.h b/xfa/src/fgas/include/fx_utl.h new file mode 100644 index 0000000000..3bb7b61986 --- /dev/null +++ b/xfa/src/fgas/include/fx_utl.h @@ -0,0 +1,797 @@ +// 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 +#define _FX_UTILS +class CFX_ThreadLock; +class CFX_BaseArray; +template class CFX_BaseArrayTemplate; +template class CFX_ObjectBaseArrayTemplate; +class CFX_BaseMassArray; +template class CFX_MassArrayTemplate; +template class CFX_ObjectMassArrayTemplate; +class CFX_BaseDiscreteArray; +template class CFX_DiscreteArrayTemplate; +class CFX_BaseStack; +template class CFX_StackTemplate; +template class CFX_ObjectStackTemplate; +template class CFX_CPLTreeNode; +template class CFX_CPLTree; +class CFX_ThreadLock +{ +public: + CFX_ThreadLock(); + virtual ~CFX_ThreadLock(); + void Lock(); + void Unlock(); +private: + FX_LPVOID m_pData; +}; +class CFX_BaseArray : public CFX_Target +{ +protected: + CFX_BaseArray(FX_INT32 iGrowSize, FX_INT32 iBlockSize); + ~CFX_BaseArray(); + FX_INT32 GetSize() const; + FX_INT32 GetBlockSize() const; + FX_LPBYTE AddSpaceTo(FX_INT32 index); + FX_LPBYTE GetAt(FX_INT32 index) const; + FX_LPBYTE GetBuffer() const; + FX_INT32 Append(const CFX_BaseArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 Copy(const CFX_BaseArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 RemoveLast(FX_INT32 iCount = -1); + void RemoveAll(FX_BOOL bLeaveMemory = FALSE); + FX_LPVOID m_pData; +}; +template +class CFX_BaseArrayTemplate : public CFX_BaseArray +{ +public: + CFX_BaseArrayTemplate(FX_INT32 iGrowSize = 100) : CFX_BaseArray(iGrowSize, sizeof(baseType)) {} + CFX_BaseArrayTemplate(FX_INT32 iGrowSize, FX_INT32 iBlockSize) : CFX_BaseArray(iGrowSize, iBlockSize) {} + FX_INT32 GetSize() const + { + return CFX_BaseArray::GetSize(); + } + FX_INT32 GetBlockSize() const + { + return CFX_BaseArray::GetBlockSize(); + } + baseType* AddSpace() + { + return (baseType*)CFX_BaseArray::AddSpaceTo(CFX_BaseArray::GetSize()); + } + FX_INT32 Add(const baseType &element) + { + FX_INT32 index = CFX_BaseArray::GetSize(); + *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element; + return index; + } + baseType* GetBuffer() const + { + return (baseType*)CFX_BaseArray::GetBuffer(); + } + baseType& GetAt(FX_INT32 index) const + { + return *(baseType*)CFX_BaseArray::GetAt(index); + } + baseType* GetPtrAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseArray::GetAt(index); + } + void SetAt(FX_INT32 index, const baseType &element) + { + *(baseType*)CFX_BaseArray::GetAt(index) = element; + } + void SetAtGrow(FX_INT32 index, const baseType &element) + { + *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element; + } + FX_INT32 Append(const CFX_BaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + return CFX_BaseArray::Append(src, iStart, iCount); + } + FX_INT32 Copy(const CFX_BaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + return CFX_BaseArray::Copy(src, iStart, iCount); + } + FX_INT32 RemoveLast(FX_INT32 iCount = -1) + { + return CFX_BaseArray::RemoveLast(iCount); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + CFX_BaseArray::RemoveAll(bLeaveMemory); + } +}; +typedef CFX_BaseArrayTemplate CFDE_PtrArray; +typedef CFX_BaseArrayTemplate CFDE_DWordArray; +typedef CFX_BaseArrayTemplate CFDE_WordArray; +template +class CFX_ObjectBaseArrayTemplate : public CFX_BaseArray +{ +public: + CFX_ObjectBaseArrayTemplate(FX_INT32 iGrowSize = 100) : CFX_BaseArray(iGrowSize, sizeof(baseType)) {} + ~CFX_ObjectBaseArrayTemplate() + { + RemoveAll(FALSE); + } + FX_INT32 GetSize() const + { + return CFX_BaseArray::GetSize(); + } + FX_INT32 GetBlockSize() const + { + return CFX_BaseArray::GetBlockSize(); + } + FX_INT32 Add(const baseType &element) + { + FX_INT32 index = CFX_BaseArray::GetSize(); + baseType *p = (baseType*)CFX_BaseArray::AddSpaceTo(index); + FXTARGET_New ((void*)p)baseType(element); + return index; + } + baseType& GetAt(FX_INT32 index) const + { + return *(baseType*)CFX_BaseArray::GetAt(index); + } + baseType* GetPtrAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseArray::GetAt(index); + } + FX_INT32 Append(const CFX_ObjectBaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + FXSYS_assert(GetBlockSize() == src.GetBlockSize()); + if (iCount == 0) { + return 0; + } + FX_INT32 iSize = src.GetSize(); + FXSYS_assert(iStart > -1 && iStart < iSize); + if (iCount < 0) { + iCount = iSize; + } + if (iStart + iCount > iSize) { + iCount = iSize - iStart; + } + if (iCount < 1) { + return 0; + } + iSize = CFX_BaseArray::GetSize(); + CFX_BaseArray::AddSpaceTo(iSize + iCount - 1); + FX_LPBYTE *pStart = CFX_BaseArray::GetAt(iSize); + FX_INT32 iBlockSize = CFX_BaseArray::GetBlockSize(); + iSize = iStart + iCount; + for (FX_INT32 i = iStart; i < iSize; i ++) { + FXTARGET_NewWith ((void*)pStart)baseType(src.GetAt(i)); + pStart += iBlockSize; + } + return iCount; + } + FX_INT32 Copy(const CFX_ObjectBaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + FXSYS_assert(GetBlockSize() == src.GetBlockSize()); + if (iCount == 0) { + return 0; + } + FX_INT32 iSize = src.GetSize(); + FXSYS_assert(iStart > -1 && iStart < iSize); + if (iCount < 0) { + iCount = iSize; + } + if (iStart + iCount > iSize) { + iCount = iSize - iStart; + } + if (iCount < 1) { + return 0; + } + RemoveAll(TRUE); + CFX_BaseArray::AddSpaceTo(iCount - 1); + FX_LPBYTE *pStart = CFX_BaseArray::GetAt(0); + FX_INT32 iBlockSize = CFX_BaseArray::GetBlockSize(); + iSize = iStart + iCount; + for (FX_INT32 i = iStart; i < iSize; i ++) { + FXTARGET_New ((void*)pStart)baseType(src.GetAt(i)); + pStart += iBlockSize; + } + return iCount; + } + FX_INT32 RemoveLast(FX_INT32 iCount = -1) + { + FX_INT32 iSize = CFX_BaseArray::GetSize(); + if (iCount < 0 || iCount > iSize) { + iCount = iSize; + } + if (iCount == 0) { + return iSize; + } + for (FX_INT32 i = iSize - iCount; i < iSize; i ++) { + ((baseType*)GetPtrAt(i))->~baseType(); + } + return CFX_BaseArray::RemoveLast(iCount); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + FX_INT32 iSize = CFX_BaseArray::GetSize(); + for (FX_INT32 i = 0; i < iSize; i ++) { + ((baseType*)GetPtrAt(i))->~baseType(); + } + CFX_BaseArray::RemoveAll(bLeaveMemory); + } +}; +class CFX_BaseMassArray : public CFX_Target +{ +protected: + CFX_BaseMassArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize); + ~CFX_BaseMassArray(); + FX_INT32 GetSize() const; + FX_LPBYTE AddSpaceTo(FX_INT32 index); + FX_LPBYTE GetAt(FX_INT32 index) const; + FX_INT32 Append(const CFX_BaseMassArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 Copy(const CFX_BaseMassArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 RemoveLast(FX_INT32 iCount = -1); + void RemoveAll(FX_BOOL bLeaveMemory = FALSE); + FX_LPVOID m_pData; +}; +template +class CFX_MassArrayTemplate : public CFX_BaseMassArray +{ +public: + CFX_MassArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {} + CFX_MassArrayTemplate(FX_INT32 iChunkSize, FX_INT32 iBlockSize) : CFX_BaseMassArray(iChunkSize, iBlockSize) {} + FX_INT32 GetSize() const + { + return CFX_BaseMassArray::GetSize(); + } + baseType* AddSpace() + { + return (baseType*)CFX_BaseMassArray::AddSpaceTo(CFX_BaseMassArray::GetSize()); + } + FX_INT32 Add(const baseType &element) + { + FX_INT32 index = CFX_BaseMassArray::GetSize(); + *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element; + return index; + } + baseType& GetAt(FX_INT32 index) const + { + return *(baseType*)CFX_BaseMassArray::GetAt(index); + } + baseType* GetPtrAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseMassArray::GetAt(index); + } + void SetAt(FX_INT32 index, const baseType &element) + { + *(baseType*)CFX_BaseMassArray::GetAt(index) = element; + } + void SetAtGrow(FX_INT32 index, const baseType &element) + { + *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element; + } + FX_INT32 Append(const CFX_MassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + return CFX_BaseMassArray::Append(src, iStart, iCount); + } + FX_INT32 Copy(const CFX_MassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + return CFX_BaseMassArray::Copy(src, iStart, iCount); + } + FX_INT32 RemoveLast(FX_INT32 iCount = -1) + { + return CFX_BaseMassArray::RemoveLast(iCount); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + CFX_BaseMassArray::RemoveAll(bLeaveMemory); + } +}; +typedef CFX_MassArrayTemplate CFX_PtrMassArray; +typedef CFX_MassArrayTemplate CFX_Int32MassArray; +typedef CFX_MassArrayTemplate CFX_DWordMassArray; +typedef CFX_MassArrayTemplate CFX_WordMassArray; +typedef CFX_MassArrayTemplate CFX_RectMassArray; +typedef CFX_MassArrayTemplate CFX_RectFMassArray; +template +class CFX_ObjectMassArrayTemplate : public CFX_BaseMassArray +{ +public: + CFX_ObjectMassArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {} + ~CFX_ObjectMassArrayTemplate() + { + RemoveAll(FALSE); + } + FX_INT32 GetSize() const + { + return CFX_BaseMassArray::GetSize(); + } + FX_INT32 Add(const baseType &element) + { + FX_INT32 index = CFX_BaseMassArray::GetSize(); + baseType *p = (baseType*)CFX_BaseMassArray::AddSpaceTo(index); + FXTARGET_New ((void*)p)baseType(element); + return index; + } + baseType& GetAt(FX_INT32 index) const + { + return *(baseType*)CFX_BaseMassArray::GetAt(index); + } + baseType* GetPtrAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseMassArray::GetAt(index); + } + FX_INT32 Append(const CFX_ObjectMassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + if (iCount == 0) { + return CFX_BaseMassArray::GetSize(); + } + FX_INT32 iSize = src.GetSize(); + FXSYS_assert(iStart > -1 && iStart < iSize); + if (iCount < 0) { + iCount = iSize; + } + FX_INT32 iEnd = iStart + iCount; + if (iEnd > iSize) { + iEnd = iSize; + } + for (FX_INT32 i = iStart; i < iEnd; i ++) { + Add(src.GetAt(i)); + } + return CFX_BaseMassArray::GetSize(); + } + FX_INT32 Copy(const CFX_ObjectMassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + if (iCount == 0) { + return CFX_BaseMassArray::GetSize(); + } + FX_INT32 iSize = src.GetSize(); + FXSYS_assert(iStart > -1 && iStart < iSize); + if (iCount < 0) { + iCount = iSize; + } + FX_INT32 iEnd = iStart + iCount; + if (iEnd > iSize) { + iEnd = iSize; + } + RemoveAll(TRUE); + for (FX_INT32 i = iStart; i < iEnd; i ++) { + Add(src.GetAt(i)); + } + return CFX_BaseMassArray::GetSize(); + } + FX_INT32 RemoveLast(FX_INT32 iCount = -1) + { + FX_INT32 iSize = CFX_BaseMassArray::GetSize(); + if (iCount < 0 || iCount > iSize) { + iCount = iSize; + } + if (iCount == 0) { + return iSize; + } + for (FX_INT32 i = iSize - iCount; i < iSize; i ++) { + ((baseType*)GetPtrAt(i))->~baseType(); + } + return CFX_BaseMassArray::RemoveLast(iCount); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + FX_INT32 iSize = CFX_BaseMassArray::GetSize(); + for (FX_INT32 i = 0; i < iSize; i ++) { + ((baseType*)GetPtrAt(i))->~baseType(); + } + CFX_BaseMassArray::RemoveAll(bLeaveMemory); + } +}; +class CFX_BaseDiscreteArray : public CFX_Target +{ +protected: + CFX_BaseDiscreteArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize); + ~CFX_BaseDiscreteArray(); + FX_LPBYTE AddSpaceTo(FX_INT32 index); + FX_LPBYTE GetAt(FX_INT32 index) const; + void RemoveAll(); + FX_LPVOID m_pData; +}; +template +class CFX_DiscreteArrayTemplate : public CFX_BaseDiscreteArray +{ +public: + CFX_DiscreteArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseDiscreteArray(iChunkSize, sizeof(baseType)) {} + baseType& GetAt(FX_INT32 index, const baseType &defValue) const + { + baseType *p = (baseType*)CFX_BaseDiscreteArray::GetAt(index); + return p == NULL ? (baseType&)defValue : *p; + } + baseType* GetPtrAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseDiscreteArray::GetAt(index); + } + void SetAtGrow(FX_INT32 index, const baseType &element) + { + *(baseType*)CFX_BaseDiscreteArray::AddSpaceTo(index) = element; + } + void RemoveAll() + { + CFX_BaseDiscreteArray::RemoveAll(); + } +}; +typedef CFX_DiscreteArrayTemplate CFX_PtrDiscreteArray; +typedef CFX_DiscreteArrayTemplate CFX_DWordDiscreteArray; +typedef CFX_DiscreteArrayTemplate CFX_WordDiscreteArray; +class CFX_BaseStack : public CFX_Target +{ +protected: + CFX_BaseStack(FX_INT32 iChunkSize, FX_INT32 iBlockSize); + ~CFX_BaseStack(); + FX_LPBYTE Push(); + void Pop(); + FX_LPBYTE GetTopElement() const; + FX_INT32 GetSize() const; + FX_LPBYTE GetAt(FX_INT32 index) const; + void RemoveAll(FX_BOOL bLeaveMemory = FALSE); + FX_LPVOID m_pData; +}; +template +class CFX_StackTemplate : public CFX_BaseStack +{ +public: + CFX_StackTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseStack(iChunkSize, sizeof(baseType)) {} + FX_INT32 Push(const baseType &element) + { + FX_INT32 index = CFX_BaseStack::GetSize(); + *(baseType*)CFX_BaseStack::Push() = element; + return index; + } + void Pop() + { + CFX_BaseStack::Pop(); + } + baseType* GetTopElement() const + { + return (baseType*)CFX_BaseStack::GetTopElement(); + } + FX_INT32 GetSize() const + { + return CFX_BaseStack::GetSize(); + } + baseType* GetAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseStack::GetAt(index); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + CFX_BaseStack::RemoveAll(bLeaveMemory); + } +}; +typedef CFX_StackTemplate CFX_PtrStack; +typedef CFX_StackTemplate CFX_DWordStack; +typedef CFX_StackTemplate CFX_WordStack; +typedef CFX_StackTemplate CFX_Int32Stack; +template +class CFX_ObjectStackTemplate : public CFX_BaseStack +{ +public: + CFX_ObjectStackTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseStack(iChunkSize, sizeof(baseType)) {} + ~CFX_ObjectStackTemplate() + { + RemoveAll(); + } + FX_INT32 Push(const baseType &element) + { + FX_INT32 index = CFX_BaseStack::GetSize(); + baseType *p = (baseType*)CFX_BaseStack::Push(); + FXTARGET_New ((void*)p)baseType(element); + return index; + } + void Pop() + { + baseType *p = (baseType*)CFX_BaseStack::GetTopElement(); + if (p != NULL) { + p->~baseType(); + } + CFX_BaseStack::Pop(); + } + baseType* GetTopElement() const + { + return (baseType*)CFX_BaseStack::GetTopElement(); + } + FX_INT32 GetSize() const + { + return CFX_BaseStack::GetSize(); + } + baseType* GetAt(FX_INT32 index) const + { + return (baseType*)CFX_BaseStack::GetAt(index); + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + FX_INT32 iSize = CFX_BaseStack::GetSize(); + for (FX_INT32 i = 0; i < iSize; i ++) { + ((baseType*)CFX_BaseStack::GetAt(i))->~baseType(); + } + CFX_BaseStack::RemoveAll(bLeaveMemory); + } + FX_INT32 Copy(const CFX_ObjectStackTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1) + { + if (iCount == 0) { + return CFX_BaseStack::GetSize(); + } + FX_INT32 iSize = src.GetSize(); + FXSYS_assert(iStart > -1 && iStart < iSize); + if (iCount < 0) { + iCount = iSize; + } + FX_INT32 iEnd = iStart + iCount; + if (iEnd > iSize) { + iEnd = iSize; + } + RemoveAll(TRUE); + for (FX_INT32 i = iStart; i < iEnd; i ++) { + Push(*src.GetAt(i)); + } + return CFX_BaseStack::GetSize(); + } +}; +template +class CFX_CPLTreeNode : public CFX_Target +{ +public: + typedef CFX_CPLTreeNode CPLTreeNode; + CFX_CPLTreeNode() : m_pParentNode(NULL) + , m_pChildNode(NULL) + , m_pPrevNode(NULL) + , m_pNextNode(NULL) + , m_Data() + { + } + enum TreeNode {Root = 0, Parent, FirstSibling, PreviousSibling, NextSibling, LastSibling, FirstNeighbor, PreviousNeighbor, NextNeighbor, LastNeighbor, FirstChild, LastChild}; + CPLTreeNode* GetNode(TreeNode eNode) const + { + switch (eNode) { + case Root: { + CPLTreeNode *pParent = (CPLTreeNode*)this; + CPLTreeNode *pTemp; + while ((pTemp = pParent->m_pParentNode) != NULL) { + pParent = pTemp; + } + return pParent; + } + case Parent: + return m_pParentNode; + case FirstSibling: { + CPLTreeNode *pNode = (CPLTreeNode*)this; + CPLTreeNode *pTemp; + while ((pTemp = pNode->m_pPrevNode) != NULL) { + pNode = pTemp; + } + return pNode == (CPLTreeNode*)this ? NULL : pNode; + } + case PreviousSibling: + return m_pPrevNode; + case NextSibling: + return m_pNextNode; + case LastSibling: { + CPLTreeNode *pNode = (CPLTreeNode*)this; + CPLTreeNode *pTemp; + while ((pTemp = pNode->m_pNextNode) != NULL) { + pNode = pTemp; + } + return pNode == (CPLTreeNode*)this ? NULL : pNode; + } + case FirstNeighbor: { + CPLTreeNode *pParent = (CPLTreeNode*)this; + CPLTreeNode *pTemp; + while ((pTemp = pParent->m_pParentNode) != NULL) { + pParent = pTemp; + } + return pParent == (CPLTreeNode*)this ? NULL : pParent; + } + case PreviousNeighbor: { + if (m_pPrevNode == NULL) { + return m_pParentNode; + } + CPLTreeNode *pNode = m_pPrevNode; + CPLTreeNode *pTemp; + while ((pTemp = pNode->m_pChildNode) != NULL) { + pNode = pTemp; + while ((pTemp = pNode->m_pNextNode) != NULL) { + pNode = pTemp; + } + } + return pNode; + } + case NextNeighbor: { + if (m_pChildNode != NULL) { + return m_pChildNode; + } + if (m_pNextNode != NULL) { + return m_pNextNode; + } + CPLTreeNode *pNode = m_pParentNode; + while (pNode != NULL) { + if (pNode->m_pNextNode != NULL) { + return pNode->m_pNextNode; + } + pNode = pNode->m_pParentNode; + } + return NULL; + } + case LastNeighbor: { + CPLTreeNode *pNode = (CPLTreeNode*)this; + CPLTreeNode *pTemp; + while ((pTemp = pNode->m_pParentNode) != NULL) { + pNode = pTemp; + } + while (TRUE) { + CPLTreeNode *pTemp; + while ((pTemp = pNode->m_pNextNode) != NULL) { + pNode = pTemp; + } + if (pNode->m_pChildNode == NULL) { + break; + } + pNode = pNode->m_pChildNode; + } + return pNode == (CPLTreeNode*)this ? NULL : pNode; + } + case FirstChild: + return m_pChildNode; + case LastChild: { + if (m_pChildNode == NULL) { + return NULL; + } + CPLTreeNode *pChild = m_pChildNode; + CPLTreeNode *pTemp; + while ((pTemp = pChild->m_pNextNode) != NULL) { + pChild = pTemp; + } + return pChild; + } + default: + break; + } + return NULL; + } + void SetParentNode(CPLTreeNode *pNode) + { + m_pParentNode = pNode; + } + FX_INT32 CountChildNodes() const + { + FX_INT32 iCount = 0; + CPLTreeNode *pNode = m_pChildNode; + while (pNode) { + iCount ++; + pNode = pNode->m_pNextNode; + } + return iCount; + } + CPLTreeNode* GetChildNode(FX_INT32 iIndex) const + { + FX_INT32 iCount = 0; + CPLTreeNode *pNode = m_pChildNode; + while (pNode) { + if (iIndex == iCount) { + return pNode; + } + iCount ++; + pNode = pNode->m_pNextNode; + } + return NULL; + } + FX_INT32 GetNodeIndex() const + { + FX_INT32 index = 0; + CPLTreeNode *pNode = m_pPrevNode; + while (pNode != NULL) { + index ++; + pNode = pNode->m_pPrevNode; + } + return index; + } + FX_BOOL IsParentNode(const CPLTreeNode *pNode) const + { + CPLTreeNode *pParent = m_pParentNode; + while (pParent != NULL) { + if (pParent == pNode) { + return TRUE; + } + pParent = pParent->GetTreeNode(Parent); + } + return FALSE; + } + FX_BOOL IsChildNode(const CPLTreeNode *pNode) const + { + if (pNode == NULL) { + return FALSE; + } + return pNode->IsParentNode((const CPLTreeNode*)this); + } + void SetChildNode(CPLTreeNode *pNode) + { + m_pChildNode = pNode; + } + void SetPrevNode(CPLTreeNode *pNode) + { + m_pPrevNode = pNode; + } + void SetNextNode(CPLTreeNode *pNode) + { + m_pNextNode = pNode; + } + FX_INT32 GetNodeLevel() const + { + FX_INT32 iLevel = 0; + CPLTreeNode *pNode = (CPLTreeNode*)this; + while ((pNode = pNode->m_pParentNode) != NULL) { + iLevel ++; + } + return iLevel; + } + FX_BOOL IsRootNode() const + { + return m_pParentNode == NULL; + } + baseType GetData() const + { + return m_Data; + } + void SetData(baseType data) + { + m_Data = data; + } +protected: + CPLTreeNode *m_pParentNode; + CPLTreeNode *m_pChildNode; + CPLTreeNode *m_pPrevNode; + CPLTreeNode *m_pNextNode; + baseType m_Data; + friend class CFX_CPLTree; +}; +template +class CFX_CPLTree : public CFX_Object +{ +public: + typedef CFX_CPLTreeNode CPLTreeNode; + CFX_CPLTree() : m_Root() + { + } + ~CFX_CPLTree() + { + CPLTreeNode *pNode = m_Root.GetNode(CPLTreeNode::LastNeighbor); + while (pNode != NULL) { + if (pNode->IsRootNode()) { + break; + } + CPLTreeNode *pTemp = pNode->GetNode(CPLTreeNode::PreviousNeighbor); + delete pNode; + pNode = pTemp; + } + } + CPLTreeNode* GetRoot() + { + return &m_Root; + } + CPLTreeNode* AddChild(baseType data, CPLTreeNode *pParent = NULL) + { + if (pParent == NULL) { + pParent = &m_Root; + } + CPLTreeNode *pChild = FXTARGET_New CPLTreeNode; + pChild->SetParentNode(pParent); + pChild->SetData(data); + if (pParent->m_pChildNode == NULL) { + pParent->m_pChildNode = pChild; + } else { + CPLTreeNode *pLast = pParent->GetNode(CPLTreeNode::LastChild); + pChild->SetPrevNode(pLast); + pLast->SetNextNode(pChild); + } + return pChild; + } +protected: + CPLTreeNode m_Root; +}; +#endif diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu874.cpp b/xfa/src/fgas/src/crt/codepage/cpcu874.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu874.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu932.cpp b/xfa/src/fgas/src/crt/codepage/cpcu932.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu932.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu936.cpp b/xfa/src/fgas/src/crt/codepage/cpcu936.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu936.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu949.cpp b/xfa/src/fgas/src/crt/codepage/cpcu949.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu949.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpcu950.cpp b/xfa/src/fgas/src/crt/codepage/cpcu950.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpcu950.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1250.cpp b/xfa/src/fgas/src/crt/codepage/cphi1250.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1250.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1251.cpp b/xfa/src/fgas/src/crt/codepage/cphi1251.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1251.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1252.cpp b/xfa/src/fgas/src/crt/codepage/cphi1252.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1252.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1253.cpp b/xfa/src/fgas/src/crt/codepage/cphi1253.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1253.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1254.cpp b/xfa/src/fgas/src/crt/codepage/cphi1254.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1254.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1255.cpp b/xfa/src/fgas/src/crt/codepage/cphi1255.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1255.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1256.cpp b/xfa/src/fgas/src/crt/codepage/cphi1256.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1256.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1257.cpp b/xfa/src/fgas/src/crt/codepage/cphi1257.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1257.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi1258.cpp b/xfa/src/fgas/src/crt/codepage/cphi1258.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi1258.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi874.cpp b/xfa/src/fgas/src/crt/codepage/cphi874.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi874.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi932.cpp b/xfa/src/fgas/src/crt/codepage/cphi932.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi932.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi936.cpp b/xfa/src/fgas/src/crt/codepage/cphi936.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi936.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi949.cpp b/xfa/src/fgas/src/crt/codepage/cphi949.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi949.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cphi950.cpp b/xfa/src/fgas/src/crt/codepage/cphi950.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cphi950.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc874.cpp b/xfa/src/fgas/src/crt/codepage/cpuc874.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc874.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc932.cpp b/xfa/src/fgas/src/crt/codepage/cpuc932.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc932.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc936.cpp b/xfa/src/fgas/src/crt/codepage/cpuc936.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc936.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc949.cpp b/xfa/src/fgas/src/crt/codepage/cpuc949.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc949.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/codepage/cpuc950.cpp b/xfa/src/fgas/src/crt/codepage/cpuc950.cpp new file mode 100644 index 0000000000..6cd252bcf4 --- /dev/null +++ b/xfa/src/fgas/src/crt/codepage/cpuc950.cpp @@ -0,0 +1,6 @@ +// 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 + diff --git a/xfa/src/fgas/src/crt/fx_algorithm.cpp b/xfa/src/fgas/src/crt/fx_algorithm.cpp new file mode 100644 index 0000000000..e2d77d1a0e --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_algorithm.cpp @@ -0,0 +1,315 @@ +// 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 "../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, FX_INT32 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] = '='; + } +} +FX_INT32 FX_Base64EncodeA(FX_LPCBYTE pSrc, FX_INT32 iSrcLen, FX_LPSTR pDst) +{ + FXSYS_assert(pSrc != NULL); + if (iSrcLen < 1) { + return 0; + } + if (pDst == NULL) { + FX_INT32 iDstLen = iSrcLen / 3 * 4; + if ((iSrcLen % 3) != 0) { + iDstLen += 4; + } + return iDstLen; + } + FX_BASE64DATA srcData; + FX_INT32 iBytes = 3; + FX_LPSTR pDstEnd = pDst; + while (iSrcLen > 0) { + if (iSrcLen > 2) { + ((FX_LPBYTE)&srcData)[0] = *pSrc ++; + ((FX_LPBYTE)&srcData)[1] = *pSrc ++; + ((FX_LPBYTE)&srcData)[2] = *pSrc ++; + iSrcLen -= 3; + } else { + *((FX_LPDWORD)&srcData) = 0; + ((FX_LPBYTE)&srcData)[0] = *pSrc ++; + if (iSrcLen > 1) { + ((FX_LPBYTE)&srcData)[1] = *pSrc ++; + } + iBytes = iSrcLen; + iSrcLen = 0; + } + FX_Base64EncodePiece(srcData, iBytes, pDstEnd); + pDstEnd += 4; + } + return pDstEnd - pDst; +} +const static FX_BYTE 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], FX_INT32 iChars, FX_BASE64DATA &dst, FX_INT32 &iBytes) +{ + FXSYS_assert(iChars > 0 && iChars < 5); + iBytes = 1; + dst.data2 = g_FXBase64DecoderMap[(FX_BYTE)src[0]]; + if (iChars > 1) { + FX_BYTE b = g_FXBase64DecoderMap[(FX_BYTE)src[1]]; + dst.data1 = b >> 4; + dst.data4 = b; + if (iChars > 2) { + iBytes = 2; + b = g_FXBase64DecoderMap[(FX_BYTE)src[2]]; + dst.data3 = b >> 2; + dst.data6 = b; + if (iChars > 3) { + iBytes = 3; + dst.data5 = g_FXBase64DecoderMap[(FX_BYTE)src[3]]; + } else { + dst.data5 = 0; + } + } else { + dst.data3 = 0; + } + } else { + dst.data1 = 0; + } +} +FX_INT32 FX_Base64DecodeA(FX_LPCSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE 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) { + FX_INT32 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; + FX_INT32 iChars = 4, iBytes; + FX_LPBYTE pDstEnd = pDst; + while (iSrcLen > 0) { + if (iSrcLen > 3) { + *((FX_DWORD*)srcData) = *((FX_DWORD*)pSrc); + pSrc += 4; + iSrcLen -= 4; + } else { + *((FX_LPDWORD)&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 ++ = ((FX_LPBYTE)&dstData)[0]; + if (iBytes > 1) { + *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1]; + } + if (iBytes > 2) { + *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2]; + } + } + return pDstEnd - pDst; +} +FX_INT32 FX_Base64DecodeW(FX_LPCWSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE 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) { + FX_INT32 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; + FX_INT32 iChars = 4, iBytes; + FX_LPBYTE 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_LPDWORD)&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 ++ = ((FX_LPBYTE)&dstData)[0]; + if (iBytes > 1) { + *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1]; + } + if (iBytes > 2) { + *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2]; + } + } + return pDstEnd - pDst; +} +const static FX_BYTE 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, +}; +FX_BYTE FX_Hex2Dec(FX_BYTE hexHigh, FX_BYTE hexLow) +{ + return (g_FXHex2DecMap[hexHigh] << 4) + g_FXHex2DecMap[hexLow]; +} +FX_INT32 FX_SeparateStringW(FX_LPCWSTR pStr, FX_INT32 iStrLen, FX_WCHAR delimiter, CFX_WideStringArray &pieces) +{ + if (pStr == NULL) { + return 0; + } + if (iStrLen < 0) { + iStrLen = FXSYS_wcslen(pStr); + } + FX_LPCWSTR pToken = pStr; + FX_LPCWSTR 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 new file mode 100644 index 0000000000..798edc9776 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_codepage.cpp @@ -0,0 +1,373 @@ +// 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 "../fgas_base.h" +#include "fx_codepage.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(FX_BYTE charset) +{ + FX_INT32 iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1; + FXSYS_assert(iEnd >= 0); + FX_INT32 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) +{ + FX_INT32 iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1; + FXSYS_assert(iEnd >= 0); + FX_INT32 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) +{ + FX_INT32 iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1; + FXSYS_assert(iEnd >= 0); + FX_INT32 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(FX_LPCSTR pStr, FX_INT32 iLength) +{ + FXSYS_assert(pStr != NULL); + if (iLength < 0) { + iLength = FXSYS_strlen(pStr); + } + if (iLength == 0) { + return 0xFFFF; + } + FX_UINT32 uHash = FX_HashCode_String_GetA(pStr, iLength, TRUE); + FX_INT32 iStart = 0, iMid; + FX_INT32 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(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + if (iLength < 0) { + iLength = FXSYS_wcslen(pStr); + } + if (iLength == 0) { + return 0xFFFF; + } + CFX_ByteString csStr; + FX_LPSTR pBuf = csStr.GetBuffer(iLength + 1); + for (FX_INT32 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_codepage.h b/xfa/src/fgas/src/crt/fx_codepage.h new file mode 100644 index 0000000000..031f4642cb --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_codepage.h @@ -0,0 +1,9 @@ +// 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_CODEPAGE_IMP +#define _FX_CODEPAGE_IMP +#endif diff --git a/xfa/src/fgas/src/crt/fx_cpmgr.cpp b/xfa/src/fgas/src/crt/fx_cpmgr.cpp new file mode 100644 index 0000000000..7bb2aa4a8d --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_cpmgr.cpp @@ -0,0 +1,65 @@ +// 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 "../fgas_base.h" +#include "fx_codepage.h" +#ifdef _FXCP +#ifdef __cplusplus +extern "C" +{ +#endif +extern const FX_CODEPAGE_HEADER g_CP936_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP932_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP949_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP950_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP874_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1250_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1251_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1252_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1253_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1254_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1255_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1256_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1257_MapHeader; +extern const FX_CODEPAGE_HEADER g_CP1258_MapHeader; +extern const FX_CPCU_MAPINFO g_CP936_CUMap; +extern const FX_CPCU_MAPINFO g_CP932_CUMap; +extern const FX_CPCU_MAPINFO g_CP949_CUMap; +extern const FX_CPCU_MAPINFO g_CP950_CUMap; +extern const FX_CPCU_MAPINFO g_CP874_CUMap; +extern const FX_CPCU_MAPINFO g_CP1250_CUMap; +extern const FX_CPCU_MAPINFO g_CP1251_CUMap; +extern const FX_CPCU_MAPINFO g_CP1252_CUMap; +extern const FX_CPCU_MAPINFO g_CP1253_CUMap; +extern const FX_CPCU_MAPINFO g_CP1254_CUMap; +extern const FX_CPCU_MAPINFO g_CP1255_CUMap; +extern const FX_CPCU_MAPINFO g_CP1256_CUMap; +extern const FX_CPCU_MAPINFO g_CP1257_CUMap; +extern const FX_CPCU_MAPINFO g_CP1258_CUMap; +FX_LPCCODEPAGE FX_GetCodePage(FX_WORD wCodePage) +{ + FX_INT32 iEnd = sizeof(g_FXCodePageMgr) / sizeof(FX_CODEPAGE) - 1; + FXSYS_assert(iEnd >= 0); + FX_INT32 iStart = 0, iMid; + FX_UINT16 uCPID; + do { + iMid = (iStart + iEnd) / 2; + const FX_CODEPAGE &cp = g_FXCodePageMgr[iMid]; + uCPID = cp.pCPHeader->uCPID; + if (wCodePage == uCPID) { + return g_FXCodePageMgr + iMid; + } else if (wCodePage < uCPID) { + iEnd = iMid - 1; + } else { + iStart = iMid + 1; + } + } while (iStart <= iEnd); + return NULL; +} +#ifdef __cplusplus +} +#endif +#endif diff --git a/xfa/src/fgas/src/crt/fx_encode.cpp b/xfa/src/fgas/src/crt/fx_encode.cpp new file mode 100644 index 0000000000..892b5a9059 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_encode.cpp @@ -0,0 +1,189 @@ +// 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 "../fgas_base.h" +#include "fx_codepage.h" +void FX_SwapByteOrder(FX_LPWSTR pStr, FX_INT32 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(FX_LPCWSTR pSrc, FX_LPWSTR pDst, FX_INT32 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(FX_LPVOID pBuffer, FX_INT32 iLength) +{ + FXSYS_assert(pBuffer != NULL && iLength > 0); + if (sizeof(FX_WCHAR) == 2) { + return; + } + FX_WORD *pSrc = (FX_WORD*)pBuffer; + FX_LPWSTR pDst = (FX_LPWSTR)pBuffer; + while (--iLength >= 0) { + pDst[iLength] = (FX_WCHAR)pSrc[iLength]; + } +} +void FX_UTF16ToWCharCopy(const FX_WORD *pUTF16, FX_LPWSTR pWChar, FX_INT32 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(FX_LPVOID pBuffer, FX_INT32 iLength) +{ + FXSYS_assert(pBuffer != NULL && iLength > 0); + if (sizeof(FX_WCHAR) == 2) { + return; + } + FX_LPCWSTR pSrc = (FX_LPCWSTR)pBuffer; + FX_WORD *pDst = (FX_WORD*)pBuffer; + while (--iLength >= 0) { + *pDst++ = (FX_WORD) * pSrc++; + } +} +void FX_WCharToUTF16Copy(FX_LPCWSTR pWChar, FX_WORD *pUTF16, FX_INT32 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(FX_LPCBYTE pStr) +{ + return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]); +} +inline FX_WORD FX_WordFromBytes(FX_LPCBYTE pStr) +{ + return (pStr[1] << 8 | pStr[0]); +} +FX_INT32 FX_DecodeString(FX_WORD wCodePage, FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen, FX_BOOL bErrBreak) +{ + if (wCodePage == FX_CODEPAGE_UTF8) { + return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen); + } + return -1; +} +FX_INT32 FX_UTF8Decode(FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen) +{ + if (pSrcLen == NULL || pDstLen == NULL) { + return -1; + } + FX_INT32 iSrcLen = *pSrcLen; + if (iSrcLen < 1) { + *pSrcLen = *pDstLen = 0; + return 1; + } + FX_INT32 iDstLen = *pDstLen; + FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0); + FX_DWORD dwCode = 0; + FX_INT32 iPending = 0; + FX_INT32 iSrcNum = 0, iDstNum = 0; + FX_INT32 k = 0; + FX_INT32 iIndex = 0; + k = 1; + while (iIndex < iSrcLen) { + FX_BYTE byte = (FX_BYTE) * (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 new file mode 100644 index 0000000000..12d081a645 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_memory.cpp @@ -0,0 +1,334 @@ +// 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 "../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 FXTARGET_New CFX_DynamicStore(chunkSize); +#endif + case FX_ALLOCTYPE_Default: + return FXTARGET_New CFX_DefStore(); + case FX_ALLOCTYPE_Static: + return FXTARGET_New CFX_StaticStore(chunkSize); + case FX_ALLOCTYPE_Fixed: + return FXTARGET_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() +{ + register 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); + register FX_LPSTATICSTORECHUNK pChunk = (FX_LPSTATICSTORECHUNK)FX_Alloc(FX_BYTE, sizeof(FX_STATICSTORECHUNK) + size); + if (pChunk == NULL) { + return NULL; + } + 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(FX_MAX(m_iDefChunkSize, size)); + } + return m_pLastChunk; +} +void* CFX_StaticStore::Alloc(size_t size) +{ + size = FX_4BYTEALIGN(size); + FXSYS_assert(size != 0); + register FX_LPSTATICSTORECHUNK pChunk = FindChunk(size); + FXSYS_assert(pChunk != NULL && pChunk->iFreeSize >= size); + register FX_LPBYTE p = (FX_LPBYTE)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() +{ + register FX_LPFIXEDSTORECHUNK pChunk, pNext; + pChunk = m_pChunk; + while (pChunk != NULL) { + pNext = pChunk->pNextChunk; + FX_Free(pChunk); + pChunk = pNext; + } +} +FX_LPFIXEDSTORECHUNK CFX_FixedStore::AllocChunk() +{ + FX_INT32 iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize + m_iBlockSize * m_iDefChunkSize; + register FX_LPFIXEDSTORECHUNK pChunk = (FX_LPFIXEDSTORECHUNK)FX_Alloc(FX_BYTE, 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; + } + register 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); + register FX_LPBYTE pFlags = pChunk->FirstFlag(); + register 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); + register FX_LPFIXEDSTORECHUNK pPrior, pChunk; + pPrior = NULL, pChunk = m_pChunk; + register FX_LPBYTE pStart = NULL, 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); + register size_t iPos = ((FX_LPBYTE)pBlock - pStart) / m_iBlockSize; + FXSYS_assert(iPos < pChunk->iChunkSize); + register FX_LPBYTE 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() +{ + register 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); + register FX_LPDYNAMICSTORECHUNK pChunk = (FX_LPDYNAMICSTORECHUNK)FX_Alloc(FX_BYTE, sizeof(FX_DYNAMICSTORECHUNK) + sizeof(FX_DYNAMICSTOREBLOCK) * 2 + size); + if (pChunk == NULL) { + return NULL; + } + pChunk->iChunkSize = size; + pChunk->iFreeSize = size; + register 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); + register FX_LPDYNAMICSTORECHUNK pChunk = m_pChunk; + register FX_LPDYNAMICSTOREBLOCK pBlock = NULL; + while (pChunk != NULL) { + if (pChunk->iFreeSize >= size) { + pBlock = pChunk->FirstBlock(); + register 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(FX_MAX(m_iDefChunkSize, size)); + pBlock = pChunk->FirstBlock(); + } + FXSYS_assert(pChunk != NULL && pBlock != NULL); + register size_t m = size + sizeof(FX_DYNAMICSTOREBLOCK); + pBlock->bUsed = TRUE; + if (pBlock->iBlockSize > m) { + register size_t n = pBlock->iBlockSize; + pBlock->iBlockSize = size; + register 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); + register FX_LPDYNAMICSTORECHUNK pPriorChunk, pChunk; + pPriorChunk = NULL, pChunk = m_pChunk; + while (pChunk != NULL) { + if (pBlock > pChunk && pBlock <= ((FX_LPBYTE)pChunk + sizeof(FX_DYNAMICSTORECHUNK) + pChunk->iChunkSize)) { + break; + } + pPriorChunk = pChunk, pChunk = pChunk->pNextChunk; + } + FXSYS_assert(pChunk != NULL); + register 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; + register size_t sizeFree = 0; + register 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 new file mode 100644 index 0000000000..9121c32c0f --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_memory.h @@ -0,0 +1,199 @@ +// 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() + { + FXTARGET_Delete this; + } + virtual void* Alloc(size_t size) + { + return FX_Alloc(FX_BYTE, 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() + { + FXTARGET_Delete this; + } + virtual void* Alloc(size_t size); + virtual void Free(FX_LPVOID 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 { + FX_LPBYTE FirstFlag() const + { + return (FX_LPBYTE)this + sizeof(_FX_FIXEDSTORECHUNK); + } + FX_LPBYTE 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() + { + FXTARGET_Delete this; + } + virtual void* Alloc(size_t size); + virtual void Free(FX_LPVOID 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); + } + FX_LPBYTE Data() const + { + return (FX_LPBYTE)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)((FX_LPBYTE)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() + { + FXTARGET_Delete this; + } + virtual void* Alloc(size_t size); + virtual void Free(FX_LPVOID 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 new file mode 100644 index 0000000000..fff3fe1e86 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_stream.cpp @@ -0,0 +1,1613 @@ +// 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 "../fgas_base.h" +#include "fx_stream.h" +IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead *pBufferRead, FX_DWORD dwAccess, FX_INT32 iFileSize, FX_BOOL bReleaseBufferRead ) +{ + CFX_Stream *pSR = FX_NEW CFX_Stream; + if (!pSR) { + return NULL; + } + if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess, bReleaseBufferRead)) { + pSR->Release(); + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (!pTR) { + pTR->Release(); + pTR = NULL; + } + return pTR; + } + return pSR; +} +IFX_Stream* IFX_Stream::CreateStream(IFX_FileRead *pFileRead, FX_DWORD dwAccess) +{ + CFX_Stream *pSR = FX_NEW CFX_Stream; + if (pSR == NULL) { + return NULL; + } + if (!pSR->LoadFileRead(pFileRead, dwAccess)) { + pSR->Release(); + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (pTR == NULL) { + pSR->Release(); + return NULL; + } + return pTR; + } + return pSR; +} +IFX_Stream* IFX_Stream::CreateStream(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess) +{ + CFX_Stream *pSR = FX_NEW CFX_Stream; + if (pSR == NULL) { + return NULL; + } + if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) { + pSR->Release(); + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (pTR == NULL) { + pSR->Release(); + return NULL; + } + return pTR; + } + return pSR; +} +IFX_Stream* IFX_Stream::CreateStream(FX_LPCWSTR pszFileName, FX_DWORD dwAccess) +{ + CFX_Stream *pSR = FX_NEW CFX_Stream; + if (pSR == NULL) { + return NULL; + } + if (!pSR->LoadFile(pszFileName, dwAccess)) { + pSR->Release(); + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (pTR == NULL) { + pSR->Release(); + return NULL; + } + return pTR; + } + return pSR; +} +IFX_Stream* IFX_Stream::CreateStream(FX_LPBYTE pData, FX_INT32 length, FX_DWORD dwAccess) +{ + CFX_Stream *pSR = FX_NEW CFX_Stream; + if (pSR == NULL) { + return NULL; + } + if (!pSR->LoadBuffer(pData, length, dwAccess)) { + pSR->Release(); + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (pTR == NULL) { + pSR->Release(); + return NULL; + } + return pTR; + } + 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(FX_LPCWSTR 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; +} +FX_INT32 CFX_FileStreamImp::GetLength() const +{ + FXSYS_assert(m_hFile != NULL); + return m_iLength; +} +FX_INT32 CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) +{ + FXSYS_assert(m_hFile != NULL); + FXSYS_fseek(m_hFile, iOffset, eSeek); + return FXSYS_ftell(m_hFile); +} +FX_INT32 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; +} +FX_INT32 CFX_FileStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(m_hFile != NULL); + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + return FXSYS_fread(pBuffer, 1, iBufferSize, m_hFile); +} +FX_INT32 CFX_FileStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) +{ + FXSYS_assert(m_hFile != NULL); + FXSYS_assert(pStr != NULL && iMaxLength > 0); + if (m_iLength <= 0) { + return 0; + } + FX_INT32 iPosition = FXSYS_ftell(m_hFile); + FX_INT32 iLen = FX_MIN((m_iLength - iPosition) / 2, iMaxLength); + if (iLen <= 0) { + return 0; + } + iLen = FXSYS_fread(pStr, 2, iLen, m_hFile); + FX_INT32 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; +} +FX_INT32 CFX_FileStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + FX_INT32 iRet = FXSYS_fwrite(pBuffer, 1, iBufferSize, m_hFile); + if (iRet != 0) { + FX_INT32 iPos = FXSYS_ftell(m_hFile); + if (iPos > m_iLength) { + m_iLength = iPos; + } + } + return iRet; +} +FX_INT32 CFX_FileStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); + FXSYS_assert(pStr != NULL && iLength > 0); + FX_INT32 iRet = FXSYS_fwrite(pStr, 2, iLength, m_hFile); + if (iRet != 0) { + FX_INT32 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(FX_INT32 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; +} +FX_INT32 CFX_FileReadStreamImp::GetLength() const +{ + return m_iLength; +} +FX_INT32 CFX_FileReadStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 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; +} +FX_INT32 CFX_FileReadStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 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; +} +FX_INT32 CFX_FileReadStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) +{ + FXSYS_assert(m_pFileRead != NULL); + FXSYS_assert(pStr != NULL && iMaxLength > 0); + iMaxLength = ReadData((FX_LPBYTE)pStr, iMaxLength * 2) / 2; + if (iMaxLength <= 0) { + return 0; + } + FX_INT32 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, FX_INT32 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; +} +FX_INT32 CFX_BufferReadStreamImp::GetLength() const +{ + return m_iBufferSize; +} +FX_INT32 CFX_BufferReadStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) +{ + FX_INT32 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; +} +FX_INT32 CFX_BufferReadStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(m_pBufferRead != NULL); + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + FX_INT32 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 < (FX_INT32)dwBlockOffset) { + if (!m_pBufferRead->ReadNextBlock(TRUE)) { + return 0; + } + dwBlockOffset = m_pBufferRead->GetBlockOffset(); + dwBlockSize = m_pBufferRead->GetBlockSize(); + } + while (m_iPosition < (FX_INT32)dwBlockOffset || m_iPosition >= (FX_INT32)(dwBlockOffset + dwBlockSize)) { + if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) { + break; + } + dwBlockOffset = m_pBufferRead->GetBlockOffset(); + dwBlockSize = m_pBufferRead->GetBlockSize(); + } + if (m_iPosition < (FX_INT32)dwBlockOffset || m_iPosition >= (FX_INT32)(dwBlockOffset + dwBlockSize)) { + return 0; + } + FX_LPCBYTE pBufferTmp = m_pBufferRead->GetBlockBuffer(); + FX_DWORD dwOffsetTmp = m_iPosition - dwBlockOffset; + FX_DWORD dwCopySize = FX_MIN(iBufferSize, (FX_INT32)(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 = FX_MIN((FX_DWORD)iBufferSize, dwBlockSize); + FXSYS_memcpy(pBuffer + dwOffsetTmp, pBufferTmp, dwCopySize); + dwOffsetTmp += dwCopySize; + iBufferSize -= dwCopySize; + } + m_iPosition += dwOffsetTmp; + return dwOffsetTmp; +} +FX_INT32 CFX_BufferReadStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) +{ + FXSYS_assert(m_pBufferRead != NULL); + FXSYS_assert(pStr != NULL && iMaxLength > 0); + iMaxLength = ReadData((FX_LPBYTE)pStr, iMaxLength * 2) / 2; + if (iMaxLength <= 0) { + return 0; + } + FX_INT32 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; +} +FX_INT32 CFX_FileWriteStreamImp::GetLength() const +{ + if (!m_pFileWrite) { + return 0; + } + return (FX_INT32)m_pFileWrite->GetSize(); +} +FX_INT32 CFX_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) +{ + FX_INT32 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(); +} +FX_INT32 CFX_FileWriteStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) +{ + if (!m_pFileWrite) { + return 0; + } + if (m_pFileWrite->WriteBlock(pBuffer, m_iPosition, iBufferSize)) { + m_iPosition += iBufferSize; + } + return iBufferSize; +} +FX_INT32 CFX_FileWriteStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + return WriteData((FX_LPCBYTE)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(FX_LPBYTE pData, FX_INT32 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; +} +FX_INT32 CFX_BufferStreamImp::GetLength() const +{ + FXSYS_assert(m_pData != NULL); + return m_iLength; +} +FX_INT32 CFX_BufferStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 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; +} +FX_INT32 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; +} +FX_INT32 CFX_BufferStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(m_pData != NULL); + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + FX_INT32 iLen = FX_MIN(m_iLength - m_iPosition, iBufferSize); + if (iLen <= 0) { + return 0; + } + FXSYS_memcpy(pBuffer, m_pData + m_iPosition, iLen); + m_iPosition += iLen; + return iLen; +} +FX_INT32 CFX_BufferStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) +{ + FXSYS_assert(m_pData != NULL); + FXSYS_assert(pStr != NULL && iMaxLength > 0); + FX_INT32 iLen = FX_MIN((m_iLength - m_iPosition) / 2, iMaxLength); + if (iLen <= 0) { + return 0; + } + FX_LPCWSTR pSrc = (FX_LPCWSTR)(FX_LPSTR)(m_pData + m_iPosition); + FX_INT32 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; +} +FX_INT32 CFX_BufferStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + FX_INT32 iLen = FX_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; +} +FX_INT32 CFX_BufferStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0); + FXSYS_assert(pStr != NULL && iLength > 0); + FX_INT32 iLen = FX_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 FX_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() +{ + FX_INT32 iPosition = m_pStreamImp->GetPosition(); + m_pStreamImp->Seek(FX_STREAMSEEK_Begin, 0); + m_pStreamImp->ReadData((FX_LPBYTE)&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, FX_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; +} +FX_INT32 CFX_TextStream::GetLength() const +{ + return m_pStreamImp->GetLength(); +} +FX_INT32 CFX_TextStream::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) +{ + return m_pStreamImp->Seek(eSeek, iOffset); +} +FX_INT32 CFX_TextStream::GetPosition() +{ + return m_pStreamImp->GetPosition(); +} +FX_BOOL CFX_TextStream::IsEOF() const +{ + return m_pStreamImp->IsEOF(); +} +FX_INT32 CFX_TextStream::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) +{ + return m_pStreamImp->ReadData(pBuffer, iBufferSize); +} +FX_INT32 CFX_TextStream::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) +{ + return m_pStreamImp->WriteData(pBuffer, iBufferSize); +} +void CFX_TextStream::Flush() +{ + m_pStreamImp->Flush(); +} +FX_BOOL CFX_TextStream::SetLength(FX_INT32 iLength) +{ + return m_pStreamImp->SetLength(iLength); +} +FX_WORD CFX_TextStream::GetCodePage() const +{ + return m_wCodePage; +} +IFX_Stream* CFX_TextStream::CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength) +{ + IFX_Stream *pSR = m_pStreamImp->CreateSharedStream(dwAccess, iOffset, iLength); + if (pSR == NULL) { + return NULL; + } + if (dwAccess & FX_STREAMACCESS_Text) { + IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE); + if (pTR == NULL) { + pSR->Release(); + return NULL; + } + return pTR; + } + return pSR; +} +FX_INT32 CFX_TextStream::GetBOM(FX_BYTE bom[4]) const +{ + if (m_wBOMLength < 1) { + return 0; + } + *(FX_DWORD*)bom = m_dwBOM; + return (FX_INT32)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; +} +FX_INT32 CFX_TextStream::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize) +{ + FXSYS_assert(pStr != NULL && iMaxLength > 0); + if (m_pStreamImp == NULL) { + return -1; + } + FX_INT32 iLen; + if (m_wCodePage == FX_CODEPAGE_UTF16LE || m_wCodePage == FX_CODEPAGE_UTF16BE) { + FX_INT32 iBytes = pByteSize == NULL ? iMaxLength * 2 : *pByteSize; + m_pStreamImp->Lock(); + iLen = m_pStreamImp->ReadData((FX_LPBYTE)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 { + FX_INT32 pos = m_pStreamImp->GetPosition(); + FX_INT32 iBytes = pByteSize == NULL ? iMaxLength : *pByteSize; + iBytes = FX_MIN(iBytes, m_pStreamImp->GetLength() - pos); + if (iBytes > 0) { + if (m_pBuf == NULL) { + m_pBuf = (FX_LPBYTE)FX_Alloc(FX_BYTE, iBytes); + m_iBufSize = iBytes; + } else if (iBytes > m_iBufSize) { + m_pBuf = (FX_LPBYTE)FX_Realloc(FX_BYTE, m_pBuf, iBytes); + m_iBufSize = iBytes; + } + m_pStreamImp->Lock(); + iLen = m_pStreamImp->ReadData(m_pBuf, iBytes); + FX_INT32 iSrc = iLen; + FX_INT32 iDecode = FX_DecodeString(m_wCodePage, (FX_LPCSTR)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; +} +FX_INT32 CFX_TextStream::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + FXSYS_assert(pStr != NULL && iLength > 0); + if ((m_pStreamImp->GetAccessModes() & FX_STREAMACCESS_Write) == 0) { + return -1; + } + if (m_wCodePage == FX_CODEPAGE_UTF8) { + FX_INT32 len = iLength; + CFX_UTF8Encoder encoder; + while (len -- > 0) { + encoder.Input(*pStr ++); + } + CFX_ByteStringC bsResult = encoder.GetResult(); + m_pStreamImp->Lock(); + m_pStreamImp->WriteData((FX_LPCBYTE)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(FX_LPCWSTR 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 = FX_NEW CFX_FileStreamImp(); + if (m_pStreamImp == NULL) { + return FALSE; + } + 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 = FX_NEW CFX_FileReadStreamImp(); + if (m_pStreamImp == NULL) { + return FALSE; + } + 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 = FX_NEW CFX_FileWriteStreamImp(); + if (m_pStreamImp == NULL) { + return FALSE; + } + 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(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess) +{ + if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { + return FALSE; + } + if (pData == NULL || iTotalSize < 1) { + return FALSE; + } + m_pStreamImp = FX_NEW CFX_BufferStreamImp(); + if (m_pStreamImp == NULL) { + return FALSE; + } + 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, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead) +{ + if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) { + return FALSE; + } + if (!pBufferRead) { + return FALSE; + } + m_pStreamImp = FX_NEW CFX_BufferReadStreamImp; + if (m_pStreamImp == NULL) { + return FALSE; + } + 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; +} +FX_INT32 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; +} +FX_INT32 CFX_Stream::Seek(FX_STREAMSEEK eSeek, FX_INT32 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); + } + FX_INT32 iEnd = m_iStart + m_iLength; + FX_INT32 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; +} +FX_INT32 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; +} +FX_INT32 CFX_Stream::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + if (m_pStreamImp == NULL) { + return -1; + } + FX_INT32 iLen = FX_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; +} +FX_INT32 CFX_Stream::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize) +{ + FXSYS_assert(pStr != NULL && iMaxLength > 0); + if (m_pStreamImp == NULL) { + return -1; + } + FX_INT32 iEnd = m_iStart + m_iLength; + FX_INT32 iLen = iEnd - m_iPosition; + if (pByteSize != NULL) { + iLen = FX_MIN(iLen, *pByteSize); + } + iLen = FX_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; +} +FX_INT32 CFX_Stream::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) +{ + FXSYS_assert(pBuffer != NULL && iBufferSize > 0); + if (m_pStreamImp == NULL) { + return -1; + } + if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { + return -1; + } + FX_INT32 iLen = iBufferSize; + if (m_eStreamType == FX_STREAMTYPE_Stream) { + iLen = FX_MIN(m_iStart + m_iTotalSize - m_iPosition, iBufferSize); + if (iLen <= 0) { + return 0; + } + } + m_pStreamImp->Lock(); + FX_INT32 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; +} +FX_INT32 CFX_Stream::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) +{ + FXSYS_assert(pStr != NULL && iLength > 0); + if (m_pStreamImp == NULL) { + return -1; + } + if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { + return -1; + } + FX_INT32 iLen = iLength; + if (m_eStreamType == FX_STREAMTYPE_Stream) { + iLen = FX_MIN((m_iStart + m_iTotalSize - m_iPosition) / 2, iLength); + if (iLen <= 0) { + return 0; + } + } + m_pStreamImp->Lock(); + FX_INT32 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(FX_INT32 iLength) +{ + if (m_pStreamImp == NULL) { + return FALSE; + } + if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) { + return FALSE; + } + return m_pStreamImp->SetLength(iLength); +} +FX_INT32 CFX_Stream::GetBOM(FX_BYTE 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, FX_INT32 iOffset, FX_INT32 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; + } + register FX_INT32 iStart = m_iStart + iOffset; + register FX_INT32 iTotal = m_iStart + m_iLength; + if (iStart < m_iStart || iStart >= iTotal) { + return NULL; + } + register FX_INT32 iEnd = iStart + iLength; + if (iEnd < iStart || iEnd > iTotal) { + return NULL; + } + CFX_Stream *pShared = FX_NEW CFX_Stream; + if (pShared == NULL) { + return NULL; + } + 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 FX_NEW CFGAS_FileRead(pBaseStream, bReleaseStream); +} +#ifdef FX_FILESIZE +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, (FX_INT32)offset); + FX_INT32 iLen = m_pStream->ReadData((FX_LPBYTE)buffer, (FX_INT32)size); + m_pStream->Unlock(); + return iLen == (FX_INT32)size; +} +#else +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_DWORD CFGAS_FileRead::GetSize() +{ + return (FX_DWORD)m_pStream->GetLength(); +} +FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size) +{ + m_pStream->Lock(); + m_pStream->Seek(FX_STREAMSEEK_Begin, (FX_INT32)offset); + FX_INT32 iLen = m_pStream->ReadData((FX_LPBYTE)buffer, (FX_INT32)size); + m_pStream->Unlock(); + return iLen == (FX_INT32)size; +} +#endif +#ifdef FX_FILESIZE +IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize, FX_BOOL bReleaseStream) +{ + if (!pBufferRead) { + return NULL; + } + return FX_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; + } + FX_LPCBYTE pBuffer = m_pBufferRead->GetBlockBuffer(); + FX_FILESIZE dwOffset = offset - dwBlockOffset; + size_t dwCopySize = FX_MIN(size, 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 = FX_MIN(size, dwBlockSize); + FXSYS_memcpy(((FX_LPBYTE)buffer) + offset, pBuffer, dwCopySize); + offset += dwCopySize; + size -= dwCopySize; + } + return TRUE; +} +#else +IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_BOOL bReleaseStream) +{ + if (!pBufferRead) { + return NULL; + } + return FX_NEW CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream); +} +CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_INT32 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_DWORD 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_DWORD)m_pBufferRead->GetBlockSize(); + while (!m_pBufferRead->IsEOF()) { + m_pBufferRead->ReadNextBlock(FALSE); + m_iBufSize += (FX_DWORD)m_pBufferRead->GetBlockSize(); + } + return m_iBufSize; +} +FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size) +{ + if (!m_pBufferRead) { + return FALSE; + } + if (!buffer || !size) { + return TRUE; + } + FX_DWORD dwBufSize = GetSize(); + if (offset >= dwBufSize) { + return FALSE; + } + size_t dwBlockSize = m_pBufferRead->GetBlockSize(); + FX_DWORD 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_DWORD)(dwBlockOffset + dwBlockSize)) { + if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) { + break; + } + dwBlockSize = m_pBufferRead->GetBlockSize(); + dwBlockOffset = m_pBufferRead->GetBlockOffset(); + } + if (offset < dwBlockOffset || offset >= (FX_DWORD)(dwBlockOffset + dwBlockSize)) { + return FALSE; + } + FX_LPCBYTE pBuffer = m_pBufferRead->GetBlockBuffer(); + FX_DWORD dwOffset = offset - dwBlockOffset; + FX_DWORD dwCopySize = FX_MIN(size, 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 = FX_MIN(size, dwBlockSize); + FXSYS_memcpy(((FX_LPBYTE)buffer) + offset, pBuffer, dwCopySize); + offset += dwCopySize; + size -= dwCopySize; + } + return TRUE; +} +#endif +IFX_FileWrite* FX_CreateFileWrite(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream) +{ + FXSYS_assert(pBaseStream != NULL); + return FX_NEW CFGAS_FileWrite(pBaseStream, bReleaseStream); +} +#ifdef FX_FILESIZE +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((FX_LPCBYTE)pData, (FX_INT32)size) == (FX_INT32)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); + FX_INT32 iLen = m_pStream->WriteData((FX_LPBYTE)pData, (FX_INT32)size); + m_pStream->Unlock(); + return iLen == (FX_INT32)size; +} +#else +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_DWORD CFGAS_FileWrite::GetSize() +{ + return m_pStream->GetLength(); +} +FX_DWORD CFGAS_FileWrite::Flush() +{ + m_pStream->Flush(); + return 0; +} +FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, FX_DWORD size) +{ + return m_pStream->WriteData((FX_LPCBYTE)pData, (FX_INT32)size) == (FX_INT32)size; +} +FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, FX_DWORD offset, FX_DWORD size) +{ + m_pStream->Lock(); + m_pStream->Seek(FX_STREAMSEEK_Begin, offset); + FX_INT32 iLen = m_pStream->WriteData((FX_LPBYTE)pData, (FX_INT32)size); + m_pStream->Unlock(); + return iLen == (FX_INT32)size; +} +#endif diff --git a/xfa/src/fgas/src/crt/fx_stream.h b/xfa/src/fgas/src/crt/fx_stream.h new file mode 100644 index 0000000000..630a0fb77f --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_stream.h @@ -0,0 +1,405 @@ +// 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 CFX_Object +{ +public: + virtual void Release() + { + delete this; + } + virtual FX_DWORD GetAccessModes() const + { + return m_dwAccess; + } + virtual FX_INT32 GetLength() const = 0; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) = 0; + virtual FX_INT32 GetPosition() = 0; + virtual FX_BOOL IsEOF() const = 0; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) = 0; + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) = 0; + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) = 0; + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) = 0; + virtual void Flush() = 0; + virtual FX_BOOL SetLength(FX_INT32 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(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess); + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition(); + virtual FX_BOOL IsEOF() const; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength); + virtual void Flush(); + virtual FX_BOOL SetLength(FX_INT32 iLength); +protected: + FXSYS_FILE *m_hFile; + FX_INT32 m_iLength; +}; +class CFX_BufferStreamImp : public CFX_StreamImp +{ +public: + CFX_BufferStreamImp(); + virtual ~CFX_BufferStreamImp() {} + FX_BOOL LoadBuffer(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess); + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition(); + virtual FX_BOOL IsEOF() const; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength); + virtual void Flush() {} + virtual FX_BOOL SetLength(FX_INT32 iLength) + { + return FALSE; + } +protected: + FX_LPBYTE m_pData; + FX_INT32 m_iTotalSize; + FX_INT32 m_iPosition; + FX_INT32 m_iLength; +}; +class CFX_FileReadStreamImp : public CFX_StreamImp +{ +public: + CFX_FileReadStreamImp(); + virtual ~CFX_FileReadStreamImp() {} + FX_BOOL LoadFileRead(IFX_FileRead *pFileRead, FX_DWORD dwAccess); + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition() + { + return m_iPosition; + } + virtual FX_BOOL IsEOF() const; + + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) + { + return 0; + } + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) + { + return 0; + } + virtual void Flush() {} + virtual FX_BOOL SetLength(FX_INT32 iLength) + { + return FALSE; + } +protected: + IFX_FileRead *m_pFileRead; + FX_INT32 m_iPosition; + FX_INT32 m_iLength; +}; +class CFX_BufferReadStreamImp : public CFX_StreamImp +{ +public: + CFX_BufferReadStreamImp(); + ~CFX_BufferReadStreamImp(); + FX_BOOL LoadBufferRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead); + + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition() + { + return m_iPosition; + } + virtual FX_BOOL IsEOF() const; + + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) + { + return 0; + } + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) + { + return 0; + } + virtual void Flush() {} + virtual FX_BOOL SetLength(FX_INT32 iLength) + { + return FALSE; + } +private: + IFX_BufferRead *m_pBufferRead; + FX_BOOL m_bReleaseBufferRead; + FX_INT32 m_iPosition; + FX_INT32 m_iBufferSize; +}; +class CFX_FileWriteStreamImp : public CFX_StreamImp +{ +public: + CFX_FileWriteStreamImp(); + virtual ~CFX_FileWriteStreamImp() {} + FX_BOOL LoadFileWrite(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess); + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition() + { + return m_iPosition; + } + virtual FX_BOOL IsEOF() const; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) + { + return 0; + } + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) + { + return 0; + } + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength); + virtual void Flush(); + virtual FX_BOOL SetLength(FX_INT32 iLength) + { + return FALSE; + } +protected: + IFX_FileWrite *m_pFileWrite; + FX_INT32 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_Object +{ +public: + CFX_Stream(); + ~CFX_Stream(); + FX_BOOL LoadFile(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess); + FX_BOOL LoadBuffer(FX_LPBYTE pData, FX_INT32 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, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead); + virtual void Release(); + virtual IFX_Stream* Retain(); + virtual FX_DWORD GetAccessModes() const + { + return m_dwAccess; + } + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition(); + virtual FX_BOOL IsEOF() const; + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength); + virtual void Flush(); + virtual FX_BOOL SetLength(FX_INT32 iLength); + virtual FX_INT32 GetBOM(FX_BYTE 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, FX_INT32 iOffset, FX_INT32 iLength); +protected: + FX_STREAMTYPE m_eStreamType; + CFX_StreamImp *m_pStreamImp; + FX_DWORD m_dwAccess; + FX_INT32 m_iTotalSize; + FX_INT32 m_iPosition; + FX_INT32 m_iStart; + FX_INT32 m_iLength; + FX_INT32 m_iRefCount; +}; +class CFX_TextStream : public IFX_Stream, public CFX_ThreadLock, public CFX_Object +{ +public: + CFX_TextStream(IFX_Stream *pStream, FX_BOOL bDelStream); + ~CFX_TextStream(); + virtual void Release(); + virtual IFX_Stream* Retain(); + + virtual FX_DWORD GetAccessModes() const; + virtual FX_INT32 GetLength() const; + virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset); + virtual FX_INT32 GetPosition(); + virtual FX_BOOL IsEOF() const; + + virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL); + virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize); + virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength); + virtual void Flush(); + virtual FX_BOOL SetLength(FX_INT32 iLength); + + virtual FX_INT32 GetBOM(FX_BYTE 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, FX_INT32 iOffset, FX_INT32 iLength); +protected: + FX_WORD m_wCodePage; + FX_WORD m_wBOMLength; + FX_DWORD m_dwBOM; + FX_LPBYTE m_pBuf; + FX_INT32 m_iBufSize; + FX_BOOL m_bDelStream; + IFX_Stream *m_pStreamImp; + FX_INT32 m_iRefCount; + void InitStream(); +}; +#ifdef FX_FILESIZE +class CFGAS_FileRead : public IFX_FileRead, public CFX_Object +{ +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; +}; +#else +class CFGAS_FileRead : public IFX_FileRead, public CFX_Object +{ +public: + CFGAS_FileRead(IFX_Stream *pStream, FX_BOOL bReleaseStream); + virtual ~CFGAS_FileRead(); + + virtual void Release() + { + delete this; + } + virtual FX_DWORD GetSize(); + virtual FX_BOOL ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size); + +protected: + FX_BOOL m_bReleaseStream; + IFX_Stream *m_pStream; +}; +#endif +#ifdef FX_FILESIZE +class CFX_BufferAccImp : public IFX_FileRead, public CFX_Object +{ +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; +}; +#else +class CFX_BufferAccImp : public IFX_FileRead, public CFX_Object +{ +public: + CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_BOOL bReleaseStream); + virtual ~CFX_BufferAccImp(); + + virtual void Release() + { + delete this; + } + virtual FX_DWORD GetSize(); + virtual FX_BOOL ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size); + +protected: + IFX_BufferRead *m_pBufferRead; + FX_BOOL m_bReleaseStream; + FX_INT32 m_iBufSize; +}; +#endif +#ifdef FX_FILESIZE +class CFGAS_FileWrite : public IFX_FileWrite, public CFX_Object +{ +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; +}; +#else +class CFGAS_FileWrite : public IFX_FileWrite, public CFX_Object +{ +public: + CFGAS_FileWrite(IFX_Stream *pStream, FX_BOOL bReleaseStream); + virtual ~CFGAS_FileWrite(); + + virtual void Release() + { + delete this; + } + virtual FX_DWORD GetSize(); + virtual FX_DWORD Flush(); + virtual FX_BOOL WriteBlock(const void* pData, FX_DWORD size); + virtual FX_BOOL WriteBlock(const void* pData, FX_DWORD offset, FX_DWORD size); + +protected: + IFX_Stream *m_pStream; + FX_BOOL m_bReleaseStream; +}; +#endif +#endif diff --git a/xfa/src/fgas/src/crt/fx_system.cpp b/xfa/src/fgas/src/crt/fx_system.cpp new file mode 100644 index 0000000000..c8e4407a79 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_system.cpp @@ -0,0 +1,236 @@ +// 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 "../fgas_base.h" +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_ +#include +#elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_ +#include +#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_LPWSTR FX_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR 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; +} +FX_INT32 FX_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR 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; +} +FX_INT32 FX_strnicmp(FX_LPCSTR s1, FX_LPCSTR 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; +} +FX_INT32 FX_filelength(FXSYS_FILE *file) +{ + FXSYS_assert(file != NULL); +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ + return _filelength(_fileno(file)); +#else + FX_INT32 iPos = FXSYS_ftell(file); + FXSYS_fseek(file, 0, FXSYS_SEEK_END); + FX_INT32 iLen = FXSYS_ftell(file); + FXSYS_fseek(file, iPos, FXSYS_SEEK_SET); + return iLen; +#endif +} +FX_BOOL FX_fsetsize(FXSYS_FILE *file, FX_INT32 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, (FX_INT32)dwPos, 0, FILE_BEGIN); + return bRet; +#else + return FALSE; +#endif +} +FX_FLOAT FX_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength , FX_INT32 *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(FX_LPCWSTR pwsStr, FX_INT32 iLength , FX_INT32 *pUsedLen ) +{ + FXSYS_assert(pwsStr != NULL); + if (iLength < 0) { + iLength = FXSYS_wcslen(pwsStr); + } + if (iLength == 0) { + return 0.0f; + } + FX_INT32 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(FX_LPVOID pBuf, FX_INT32 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(FX_LPVOID pDst, FX_LPCVOID 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) +{ + FX_INT32 iUrlLen = wsUrl.GetLength(); + if (iUrlLen == 0) { + return TRUE; + } + for (FX_INT32 i = FX_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; + } + FX_LPCWSTR pRelStart = wsRelativePath.GetPtr(); + FX_LPCWSTR 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; + } + } + FX_INT32 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; + } + } + FX_LPCWSTR pBaseStart = wsBasePath.GetPtr(); + FX_LPCWSTR 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 new file mode 100644 index 0000000000..f13af23216 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_utils.cpp @@ -0,0 +1,456 @@ +// 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 "../fgas_base.h" +#include "fx_utils.h" +CFX_ThreadLock::CFX_ThreadLock() + : m_pData(NULL) +{ +} +CFX_ThreadLock::~CFX_ThreadLock() +{ +} +void CFX_ThreadLock::Lock() +{ +} +void CFX_ThreadLock::Unlock() +{ +} +typedef struct _FX_BASEARRAYDATA : public CFX_Target { + FX_INT32 iGrowSize; + FX_INT32 iBlockSize; + FX_INT32 iTotalCount; + FX_INT32 iBlockCount; + FX_LPBYTE pBuffer; +} FX_BASEARRAYDATA, * FX_LPBASEARRAYDATA; +typedef FX_BASEARRAYDATA const * FX_LPCBASEARRAYDATA; +CFX_BaseArray::CFX_BaseArray(FX_INT32 iGrowSize, FX_INT32 iBlockSize) +{ + FXSYS_assert(iGrowSize > 0 && iBlockSize > 0); + m_pData = FXTARGET_New FX_BASEARRAYDATA; + FX_memset(m_pData, 0, sizeof(FX_BASEARRAYDATA)); + ((FX_LPBASEARRAYDATA)m_pData)->iGrowSize = iGrowSize; + ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize = iBlockSize; +} +CFX_BaseArray::~CFX_BaseArray() +{ + FX_LPBASEARRAYDATA pData = (FX_LPBASEARRAYDATA)m_pData; + if (pData->pBuffer != NULL) { + FX_Free(pData->pBuffer); + } + FXTARGET_Delete pData; +} +FX_INT32 CFX_BaseArray::GetSize() const +{ + return ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount; +} +FX_INT32 CFX_BaseArray::GetBlockSize() const +{ + return ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize; +} +FX_LPBYTE CFX_BaseArray::AddSpaceTo(FX_INT32 index) +{ + FXSYS_assert(index > -1); + FX_LPBYTE &pBuffer = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer; + FX_INT32 &iTotalCount = ((FX_LPBASEARRAYDATA)m_pData)->iTotalCount; + FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize; + if (index >= iTotalCount) { + FX_INT32 iGrowSize = ((FX_LPBASEARRAYDATA)m_pData)->iGrowSize; + iTotalCount = (index / iGrowSize + 1) * iGrowSize; + FX_INT32 iNewSize = iTotalCount * iBlockSize; + if (pBuffer == NULL) { + pBuffer = (FX_LPBYTE)FX_Alloc(FX_BYTE, iNewSize); + } else { + pBuffer = (FX_LPBYTE)FX_Realloc(FX_BYTE, pBuffer, iNewSize); + } + } + FXSYS_assert(pBuffer != NULL); + FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount; + if (index >= iBlockCount) { + iBlockCount = index + 1; + } + return pBuffer + index * iBlockSize; +} +FX_LPBYTE CFX_BaseArray::GetAt(FX_INT32 index) const +{ + FXSYS_assert(index > -1 && index < ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount); + return ((FX_LPBASEARRAYDATA)m_pData)->pBuffer + index * ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize; +} +FX_LPBYTE CFX_BaseArray::GetBuffer() const +{ + return ((FX_LPBASEARRAYDATA)m_pData)->pBuffer; +} +FX_INT32 CFX_BaseArray::Append(const CFX_BaseArray &src, FX_INT32 iStart, FX_INT32 iCount) +{ + FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize; + FXSYS_assert(iBlockSize == ((FX_LPBASEARRAYDATA)src.m_pData)->iBlockSize); + FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount; + FX_INT32 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; + } + FX_LPBYTE pDst = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer + iBlockCount * iBlockSize; + AddSpaceTo(iBlockCount + iCount - 1); + FX_memcpy(pDst, ((FX_LPBASEARRAYDATA)src.m_pData)->pBuffer + iStart * iBlockSize, iCount * iBlockSize); + return iCount; +} +FX_INT32 CFX_BaseArray::Copy(const CFX_BaseArray &src, FX_INT32 iStart, FX_INT32 iCount) +{ + FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize; + FXSYS_assert(iBlockSize == ((FX_LPBASEARRAYDATA)src.m_pData)->iBlockSize); + FX_INT32 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(((FX_LPBASEARRAYDATA)m_pData)->pBuffer, ((FX_LPBASEARRAYDATA)src.m_pData)->pBuffer + iStart * iBlockSize, iCount * iBlockSize); + return iCount; +} +FX_INT32 CFX_BaseArray::RemoveLast(FX_INT32 iCount) +{ + FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)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) { + FX_LPBYTE &pBuffer = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer; + if (pBuffer != NULL) { + FX_Free(pBuffer); + pBuffer = NULL; + } + ((FX_LPBASEARRAYDATA)m_pData)->iTotalCount = 0; + } + ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount = 0; +} +CFX_BaseMassArrayImp::CFX_BaseMassArrayImp(FX_INT32 iChunkSize, FX_INT32 iBlockSize) + : m_iChunkSize(iChunkSize) + , m_iBlockSize(iBlockSize) + , m_iChunkCount(0) + , m_iBlockCount(0) +{ + FXSYS_assert(m_iChunkSize > 0 && m_iBlockSize > 0); + m_pData = FX_NEW CFX_PtrArray; + m_pData->SetSize(16); +} +CFX_BaseMassArrayImp::~CFX_BaseMassArrayImp() +{ + RemoveAll(); + delete m_pData; +} +FX_LPBYTE CFX_BaseMassArrayImp::AddSpaceTo(FX_INT32 index) +{ + FXSYS_assert(index > -1); + FX_LPBYTE pChunk; + if (index < m_iBlockCount) { + pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize); + } else { + FX_INT32 iMemSize = m_iChunkSize * m_iBlockSize; + while (TRUE) { + if (index < m_iChunkCount * m_iChunkSize) { + pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize); + break; + } else { + pChunk = (FX_LPBYTE)FX_Alloc(FX_BYTE, 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; +} +FX_LPBYTE CFX_BaseMassArrayImp::GetAt(FX_INT32 index) const +{ + FXSYS_assert(index > -1 && index < m_iBlockCount); + FX_LPBYTE pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize); + FXSYS_assert(pChunk != NULL); + return pChunk + (index % m_iChunkSize) * m_iBlockSize; +} +FX_INT32 CFX_BaseMassArrayImp::Append(const CFX_BaseMassArrayImp &src, FX_INT32 iStart, FX_INT32 iCount) +{ + FXSYS_assert(m_iBlockSize == src.m_iBlockSize); + FX_INT32 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; + } + FX_INT32 iBlockCount = m_iBlockCount; + FX_INT32 iTotal = m_iBlockCount + iCount; + AddSpaceTo(iTotal - 1); + Append(iBlockCount, src, iStart, iCount); + return m_iBlockCount; +} +FX_INT32 CFX_BaseMassArrayImp::Copy(const CFX_BaseMassArrayImp &src, FX_INT32 iStart, FX_INT32 iCount) +{ + FXSYS_assert(m_iBlockSize == src.m_iBlockSize); + FX_INT32 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(FX_INT32 iDstStart, const CFX_BaseMassArrayImp &src, FX_INT32 iSrcStart, FX_INT32 iSrcCount) +{ + FXSYS_assert(iDstStart > -1 && m_iBlockSize == src.m_iBlockSize); + FX_INT32 iSrcTotal = src.m_iBlockCount; + FXSYS_assert(iSrcTotal > 0 && m_iBlockCount >= iDstStart + iSrcCount); + FXSYS_assert(iSrcStart > -1 && iSrcStart < iSrcTotal && iSrcCount > 0 && iSrcStart + iSrcCount <= iSrcTotal); + FX_INT32 iDstChunkIndex = iDstStart / m_iChunkSize; + FX_INT32 iSrcChunkIndex = iSrcStart / src.m_iChunkSize; + FX_LPBYTE pDstChunk = (FX_LPBYTE)GetAt(iDstStart); + FX_LPBYTE pSrcChunk = (FX_LPBYTE)src.GetAt(iSrcStart); + FX_INT32 iDstChunkSize = m_iChunkSize - (iDstStart % m_iChunkSize); + FX_INT32 iSrcChunkSize = src.m_iChunkSize - (iSrcStart % src.m_iChunkSize); + FX_INT32 iCopySize = FX_MIN(iSrcCount, FX_MIN(iSrcChunkSize, iDstChunkSize)); + FX_INT32 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 = (FX_LPBYTE)src.m_pData->GetAt(iSrcChunkIndex); + } else { + pSrcChunk += iCopyBytes; + } + iDstChunkSize -= iCopySize; + if (iDstChunkSize < 1) { + iDstChunkSize = m_iChunkSize; + iDstChunkIndex ++; + pDstChunk = (FX_LPBYTE)m_pData->GetAt(iDstChunkIndex); + } else { + pDstChunk += iCopyBytes; + } + iCopySize = FX_MIN(iSrcCount, FX_MIN(iSrcChunkSize, iDstChunkSize)); + iCopyBytes = iCopySize * m_iBlockSize; + } +} +FX_INT32 CFX_BaseMassArrayImp::RemoveLast(FX_INT32 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 (FX_INT32 i = 0; i < m_iChunkCount; i ++) { + FX_LPVOID 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(FX_INT32 iChunkSize, FX_INT32 iBlockSize) +{ + m_pData = FXTARGET_New CFX_BaseMassArrayImp(iChunkSize, iBlockSize); +} +CFX_BaseMassArray::~CFX_BaseMassArray() +{ + FXTARGET_Delete (CFX_BaseMassArrayImp*)m_pData; +} +FX_INT32 CFX_BaseMassArray::GetSize() const +{ + return ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount; +} +FX_LPBYTE CFX_BaseMassArray::AddSpaceTo(FX_INT32 index) +{ + return ((CFX_BaseMassArrayImp*)m_pData)->AddSpaceTo(index); +} +FX_LPBYTE CFX_BaseMassArray::GetAt(FX_INT32 index) const +{ + return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(index); +} +FX_INT32 CFX_BaseMassArray::Append(const CFX_BaseMassArray &src, FX_INT32 iStart, FX_INT32 iCount) +{ + return ((CFX_BaseMassArrayImp*)m_pData)->Append(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount); +} +FX_INT32 CFX_BaseMassArray::Copy(const CFX_BaseMassArray &src, FX_INT32 iStart, FX_INT32 iCount) +{ + return ((CFX_BaseMassArrayImp*)m_pData)->Copy(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount); +} +FX_INT32 CFX_BaseMassArray::RemoveLast(FX_INT32 iCount) +{ + return ((CFX_BaseMassArrayImp*)m_pData)->RemoveLast(iCount); +} +void CFX_BaseMassArray::RemoveAll(FX_BOOL bLeaveMemory) +{ + ((CFX_BaseMassArrayImp*)m_pData)->RemoveAll(bLeaveMemory); +} +typedef struct _FX_BASEDISCRETEARRAYDATA : public CFX_Object { + FX_INT32 iBlockSize; + FX_INT32 iChunkSize; + FX_INT32 iChunkCount; + CFX_PtrArray ChunkBuffer; +} FX_BASEDISCRETEARRAYDATA, * FX_LPBASEDISCRETEARRAYDATA; +typedef FX_BASEDISCRETEARRAYDATA const * FX_LPCBASEDISCRETEARRAYDATA; +CFX_BaseDiscreteArray::CFX_BaseDiscreteArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize) +{ + FXSYS_assert(iChunkSize > 0 && iBlockSize > 0); + FX_LPBASEDISCRETEARRAYDATA pData; + m_pData = pData = FX_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; +} +FX_LPBYTE CFX_BaseDiscreteArray::AddSpaceTo(FX_INT32 index) +{ + FXSYS_assert(index > -1); + FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData; + FX_INT32 &iChunkCount = pData->iChunkCount; + FX_INT32 iChunkSize = pData->iChunkSize; + FX_LPBYTE pChunk = NULL; + FX_INT32 iChunk = index / iChunkSize; + if (iChunk < iChunkCount) { + pChunk = (FX_LPBYTE)pData->ChunkBuffer.GetAt(iChunk); + } + if (pChunk == NULL) { + FX_INT32 iMemSize = iChunkSize * pData->iBlockSize; + pChunk = (FX_LPBYTE)FX_Alloc(FX_BYTE, iMemSize); + FXSYS_memset(pChunk, 0, iMemSize); + pData->ChunkBuffer.SetAtGrow(iChunk, pChunk); + if (iChunkCount <= iChunk) { + iChunkCount = iChunk + 1; + } + } + return pChunk + (index % iChunkSize) * pData->iBlockSize; +} +FX_LPBYTE CFX_BaseDiscreteArray::GetAt(FX_INT32 index) const +{ + FXSYS_assert(index > -1); + FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData; + FX_INT32 iChunkSize = pData->iChunkSize; + FX_INT32 iChunk = index / iChunkSize; + if (iChunk >= pData->iChunkCount) { + return NULL; + } + FX_LPBYTE pChunk = (FX_LPBYTE)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; + FX_INT32 &iChunkCount = pData->iChunkCount; + for (FX_INT32 i = 0; i < iChunkCount; i++) { + FX_LPVOID p = ChunkBuffer.GetAt(i); + if (p == NULL) { + continue; + } + FX_Free(p); + } + ChunkBuffer.RemoveAll(); + iChunkCount = 0; +} +CFX_BaseStack::CFX_BaseStack(FX_INT32 iChunkSize, FX_INT32 iBlockSize) +{ + m_pData = FXTARGET_New CFX_BaseMassArrayImp(iChunkSize, iBlockSize); +} +CFX_BaseStack::~CFX_BaseStack() +{ + FXTARGET_Delete (CFX_BaseMassArrayImp*)m_pData; +} +FX_LPBYTE CFX_BaseStack::Push() +{ + return ((CFX_BaseMassArrayImp*)m_pData)->AddSpace(); +} +void CFX_BaseStack::Pop() +{ + FX_INT32 &iBlockCount = ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount; + if (iBlockCount < 1) { + return; + } + iBlockCount --; +} +FX_LPBYTE CFX_BaseStack::GetTopElement() const +{ + FX_INT32 iSize = ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount; + if (iSize < 1) { + return NULL; + } + return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(iSize - 1); +} +FX_INT32 CFX_BaseStack::GetSize() const +{ + return ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount; +} +FX_LPBYTE CFX_BaseStack::GetAt(FX_INT32 index) const +{ + return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(index); +} +void CFX_BaseStack::RemoveAll(FX_BOOL bLeaveMemory ) +{ + ((CFX_BaseMassArrayImp*)m_pData)->RemoveAll(bLeaveMemory); +} diff --git a/xfa/src/fgas/src/crt/fx_utils.h b/xfa/src/fgas/src/crt/fx_utils.h new file mode 100644 index 0000000000..a073b80e57 --- /dev/null +++ b/xfa/src/fgas/src/crt/fx_utils.h @@ -0,0 +1,32 @@ +// 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(FX_INT32 iChunkSize, FX_INT32 iBlockSize); + ~CFX_BaseMassArrayImp(); + FX_LPBYTE AddSpace() + { + return AddSpaceTo(m_iBlockCount); + } + FX_LPBYTE AddSpaceTo(FX_INT32 index); + FX_LPBYTE GetAt(FX_INT32 index) const; + FX_INT32 Append(const CFX_BaseMassArrayImp &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 Copy(const CFX_BaseMassArrayImp &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1); + FX_INT32 RemoveLast(FX_INT32 iCount = -1); + void RemoveAll(FX_BOOL bLeaveMemory = FALSE); + FX_INT32 m_iChunkSize; + FX_INT32 m_iBlockSize; + FX_INT32 m_iChunkCount; + FX_INT32 m_iBlockCount; + CFX_PtrArray *m_pData; +protected: + void Append(FX_INT32 iDstStart, const CFX_BaseMassArrayImp &src, FX_INT32 iSrcStart = 0, FX_INT32 iSrcCount = -1); +}; +#endif diff --git a/xfa/src/fgas/src/fgas_base.h b/xfa/src/fgas/src/fgas_base.h new file mode 100644 index 0000000000..d860ec3c9b --- /dev/null +++ b/xfa/src/fgas/src/fgas_base.h @@ -0,0 +1,12 @@ +// 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 _FXMATH_BASE_ +#define _FXMATH_BASE_ +#include "../../foxitlib.h" +#include "../../../../core/include/fxge/fx_freetype.h" +#include "../include/fgas.h" +#endif diff --git a/xfa/src/fgas/src/font/fx_fontutils.cpp b/xfa/src/fgas/src/font/fx_fontutils.cpp new file mode 100644 index 0000000000..b2a7028fb8 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_fontutils.cpp @@ -0,0 +1,236 @@ +// 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 "../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(FX_LPCWSTR 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((FX_LPCWSTR)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) +{ + FX_INT32 iEnd = sizeof(g_FXGdiFontUSBTable) / sizeof(FGAS_FONTUSB) - 1; + FXSYS_assert(iEnd >= 0); + FX_INT32 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 new file mode 100644 index 0000000000..1e3088fde8 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_fontutils.h @@ -0,0 +1,19 @@ +// 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(FX_LPCWSTR 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 new file mode 100644 index 0000000000..e9ab665b5a --- /dev/null +++ b/xfa/src/fgas/src/font/fx_gdifont.cpp @@ -0,0 +1,532 @@ +// 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 "../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(); + FX_INT32 iGlyph; + FX_LPGDIGOCACHE pGlyph; + while (pos != NULL) { + pGlyph = NULL; + m_GlyphMap.GetNextAssoc(pos, (void*&)iGlyph, (void*&)pGlyph); + if (pGlyph != NULL) { + FDE_Free(pGlyph->pOutline); + FDE_Free(pGlyph); + } + } + m_GlyphMap.RemoveAll(); +} +void CFX_GdiFontCache::SetCachedGlyphOutline(FX_DWORD dwGlyph, const GLYPHMETRICS &gm, FX_LPBYTE pOutline) +{ + FXSYS_assert(pOutline != NULL); + FX_LPGDIGOCACHE pGlyph = (FX_LPGDIGOCACHE)FDE_Alloc(sizeof(FX_GDIGOCACHE)); + 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(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage, IFX_FontMgr *pFontMgr) +{ + CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr); + if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) { + pFont->Release(); + return NULL; + } + return pFont; +} +IFX_Font* IFX_Font::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, IFX_FontMgr *pFontMgr) +{ + CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr); + if (!pFont->LoadFont(pBuffer, iLength)) { + pFont->Release(); + return NULL; + } + return pFont; +} +IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR pszFileName, IFX_FontMgr *pFontMgr) +{ + CFX_GdiFont *pFont = FX_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 = FX_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() +{ + FX_INT32 iCount = m_SubstFonts.GetSize(); + for (FX_INT32 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((FX_LPCWSTR)m_wsFontFileName); + } else { + ::RemoveFontMemResourceEx(m_hRes); + } + } + m_WidthCache.RemoveAll(); + ClearCache(); +} +void CFX_GdiFont::ClearCache() +{ + FX_INT32 iCount = m_SubstFonts.GetSize(); + for (FX_INT32 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(FX_LPCWSTR 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 ? (FX_BYTE)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(FX_LPCBYTE pBuffer, FX_INT32 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, (FX_LPCWSTR)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(FX_LPCWSTR 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, (FX_LPCWSTR)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); + FX_INT32 iLength = pFontStream->GetLength(); + if (iLength < 1) { + return FALSE; + } + FX_LPBYTE pBuf = (FX_LPBYTE)FDE_Alloc(iLength); + if (pBuf == NULL) { + return FALSE; + } + iLength = pFontStream->ReadData(pBuf, iLength); + FX_BOOL bRet = LoadFont(pBuf, iLength); + FDE_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; +} +FX_INT32 CFX_GdiFont::GetFontFamilies(Gdiplus::FontCollection &fc) +{ + FX_INT32 iCount = fc.GetFamilyCount(); + if (iCount < 1) { + return iCount; + } + Gdiplus::FontFamily *pFontFamilies = (Gdiplus::FontFamily*)FDE_Alloc(iCount * sizeof(Gdiplus::FontFamily)); + if (pFontFamilies == NULL) { + return -1; + } + FX_INT32 iFind = 0; + fc.GetFamilies(iCount, pFontFamilies, &iFind); + for (FX_INT32 i = 0; i < iCount; i ++) { + CFX_WideString wsFamilyName; + FX_LPWSTR pName = wsFamilyName.GetBuffer(LF_FACESIZE); + pFontFamilies[i].GetFamilyName(pName); + wsFamilyName.ReleaseBuffer(); + m_FontFamilies.Add(wsFamilyName); + } + FDE_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, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode) +{ + iWidth = (FX_INT32)(FX_SHORT)m_WidthCache.GetAt(wUnicode, 0); + if (iWidth == 0 || iWidth == -1) { + IFX_Font *pFont = NULL; + FX_INT32 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, (FX_SHORT)iWidth); + Unlock(); + } + return iWidth > 0; +} +FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode) +{ + return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode); +} +FX_INT32 CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode) +{ + FX_INT32 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) { + FX_INT32 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); + FX_INT32 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; +} +FX_INT32 CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) +{ + return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode); +} +FX_INT32 CFX_GdiFont::GetAscent() const +{ + return m_OutlineTM.otmAscent; +} +FX_INT32 CFX_GdiFont::GetDescent() const +{ + return m_OutlineTM.otmDescent; +} +FX_BOOL CFX_GdiFont::GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode) +{ + FX_INT32 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; +} +FX_INT32 CFX_GdiFont::GetItalicAngle() const +{ + return m_OutlineTM.otmItalicAngle / 10; +} +void CFX_GdiFont::Reset() +{ + Lock(); + m_WidthCache.RemoveAll(); + ClearCache(); + Unlock(); +} +IFX_Font* CFX_GdiFont::GetSubstFont(FX_INT32 iGlyphIndex) const +{ + FX_INT32 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(FX_INT32 iGlyphIndex, FX_ARGB argb, const MAT2 *pMatrix, GLYPHMETRICS &gm, FX_LPVOID 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); + } + FX_LPBYTE 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_LPBYTE)FX_Alloc(dwGlyphSize); + ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, dwGlyphSize, pGlyphOutline, pMatrix); + if (pCache == NULL) { + pCache = FX_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_LPDWORD)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(FX_INT32 iWidth, FX_INT32 iHeight, FX_LPBYTE pOutline, FX_LPDWORD pDIB, FX_ARGB argb) +{ + FX_INT32 padding = ((iWidth + 3) / 4) * 4 - iWidth; + FX_DWORD alpha; + FX_INT32 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 new file mode 100644 index 0000000000..f6d88f38a0 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_gdifont.h @@ -0,0 +1,89 @@ +// 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; + FX_LPBYTE pOutline; +} FX_GDIGOCACHE, * FX_LPGDIGOCACHE; +typedef FX_GDIGOCACHE const * FX_LPCGDIGOCACHE; +class CFX_GdiFontCache : public CFX_Object +{ +public: + CFX_GdiFontCache(); + ~CFX_GdiFontCache(); + void SetCachedGlyphOutline(FX_DWORD dwGlyph, const GLYPHMETRICS &gm, FX_LPBYTE pOutline); + FX_LPCGDIGOCACHE GetCachedGlyphOutline(FX_DWORD dwGlyph) const; +protected: + CFX_MapPtrToPtr m_GlyphMap; +}; +class CFX_GdiFont : public IFX_Font, public CFX_ThreadLock, public CFX_Object +{ +public: + CFX_GdiFont(IFX_FontMgr *pFontMgr); + ~CFX_GdiFont(); + virtual void Release(); + virtual IFX_Font* Retain(); + FX_BOOL LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage); + FX_BOOL LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength); + FX_BOOL LoadFont(FX_LPCWSTR 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 FX_BYTE GetCharSet() const + { + return m_LogFont.lfCharSet; + } + virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE); + virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE); + virtual FX_INT32 GetAscent() const; + virtual FX_INT32 GetDescent() const; + virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE); + virtual FX_BOOL GetBBox(CFX_Rect &bbox); + virtual FX_INT32 GetItalicAngle() const; + virtual void Reset(); + FX_DWORD GetGlyphDIBits(FX_INT32 iGlyphIndex, FX_ARGB argb, const MAT2 *pMatrix, GLYPHMETRICS &gm, FX_LPVOID pBuffer, FX_DWORD bufSize); + FX_DWORD GetHashCode() const; +protected: + IFX_FontMgr *m_pFontMgr; + FX_INT32 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(); + FX_INT32 GetFontFamilies(Gdiplus::FontCollection &fc); + void RetrieveFontStyles(); + IFX_Font* GetSubstFont(FX_INT32 iGlyphIndex) const; + FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE); + FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode = FALSE); + FX_DWORD GetMAT2HashCode(const FIXED *pFixed); + void CreateGlyphBitmap(FX_INT32 iWidth, FX_INT32 iHeight, FX_LPBYTE pOutline, FX_LPDWORD 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 new file mode 100644 index 0000000000..f952bc730e --- /dev/null +++ b/xfa/src/fgas/src/font/fx_gefont.cpp @@ -0,0 +1,595 @@ +// 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 "../fgas_base.h" +#include "fx_gefont.h" +#include "fx_fontutils.h" +#ifndef _FXPLUS +IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR 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 = FX_NEW CFX_GEFont(pFontMgr); + if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) { + pFont->Release(); + return NULL; + } + return pFont; +#endif +} +IFX_Font* IFX_Font::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 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 = FX_NEW CFX_GEFont(pFontMgr); + if (!pFont->LoadFont(pBuffer, iLength)) { + pFont->Release(); + return NULL; + } + return pFont; +#endif +} +IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR 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 = FX_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 = FX_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 = FX_NEW CFX_GEFont(pFontMgr); + if (!pFont->LoadFont(pExtFont, bTakeOver)) { + pFont->Release(); + return NULL; + } + return pFont; +} +CFX_GEFont::CFX_GEFont(IFX_FontMgr *pFontMgr) + : CFX_ThreadLock() + , 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_wCharSet(0xFFFF) + , m_pProvider(NULL) +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + , m_bUseLogFontStyle(FALSE) + , m_dwLogFontStyle(0) +#endif + , m_SubstFonts() + , m_FontMapper(16) +{ +} +CFX_GEFont::CFX_GEFont(const CFX_GEFont &src, FX_DWORD dwFontStyles) + : CFX_ThreadLock() + , 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_wCharSet(0xFFFF) + , m_pProvider(NULL) + , m_SubstFonts() + , m_FontMapper(16) +{ + m_pFont = FX_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->m_pSubstFont; + if (pSubst == NULL) { + pSubst = FX_NEW CFX_SubstFont; + } + if (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() +{ + FX_INT32 iCount = m_SubstFonts.GetSize(); + for (FX_INT32 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) { + FXTARGET_Delete m_pCharWidthMap; + } + if (m_pRectArray != NULL) { + FXTARGET_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(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage) +{ + if (m_pFont != NULL) { + 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; + } + FX_INT32 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 = FX_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"; + } + FX_BOOL bRet = m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage); + bRet = m_pFont->m_Face != NULL; + if (bRet) { + InitFont(); + } + Unlock(); + return bRet; +} +FX_BOOL CFX_GEFont::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 length) +{ + if (m_pFont != NULL) { + return FALSE; + } + Lock(); + m_pFont = FX_NEW CFX_Font; + FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length); + if (bRet) { + InitFont(); + } + m_wCharSet = 0xFFFF; + Unlock(); + return bRet; +} +FX_BOOL CFX_GEFont::LoadFont(FX_LPCWSTR pszFileName) +{ + if (m_pFont != NULL) { + return FALSE; + } + if (m_pStream != NULL) { + return FALSE; + } + if (m_pFileRead != NULL) { + 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 != NULL && m_pFileRead != NULL) { + m_pFont = FX_NEW CFX_Font; + bRet = m_pFont->LoadFile(m_pFileRead); + if (!bRet) { + m_pFileRead->Release(); + m_pFileRead = NULL; + } else { + InitFont(); + } + } + m_wCharSet = 0xFFFF; + Unlock(); + return bRet; +} +FX_BOOL CFX_GEFont::LoadFont(IFX_Stream *pFontStream, FX_BOOL bSaveStream) +{ + if (m_pFont != NULL) { + return FALSE; + } + if (pFontStream == NULL || pFontStream->GetLength() < 1) { + return FALSE; + } + if (m_pFileRead != NULL) { + return FALSE; + } + Lock(); + if (bSaveStream) { + m_pStream = pFontStream; + } + m_pFileRead = FX_CreateFileRead(pFontStream); + m_pFont = FX_NEW CFX_Font; + FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead); + if (!bRet) { + m_pFileRead->Release(); + m_pFileRead = NULL; + } else { + InitFont(); + } + m_wCharSet = 0xFFFF; + Unlock(); + return bRet; +} +FX_BOOL CFX_GEFont::LoadFont(CFX_Font *pExtFont, FX_BOOL bTakeOver) +{ + if (m_pFont != NULL) { + return FALSE; + } + if (pExtFont == NULL) { + return FALSE; + } + Lock(); + if ((m_pFont = pExtFont) != NULL) { + m_bExtFont = !bTakeOver; + InitFont(); + } else { + m_bExtFont = TRUE; + } + m_wCharSet = 0xFFFF; + Unlock(); + return m_pFont != NULL; +} +void CFX_GEFont::InitFont() +{ + if (m_pFont == NULL) { + return; + } + if (m_pFontEncoding == NULL) { +#ifdef FXFM_ENCODING_NONE + m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont); +#else + m_pFontEncoding = FXGE_CreateUnicodeEncoding(m_pFont); +#endif + } + if (m_pCharWidthMap == NULL) { + m_pCharWidthMap = FXTARGET_New CFX_WordDiscreteArray(1024); + } + if (m_pRectArray == NULL) { + m_pRectArray = FXTARGET_New CFX_RectMassArray(16); + } + if (m_pBBoxMap == NULL) { + m_pBBoxMap = FX_NEW CFX_MapPtrToPtr(16); + } +} +IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage ) +{ + if (GetFontStyles() == dwFontStyles) { + return Retain(); + } + return FX_NEW CFX_GEFont(*this, dwFontStyles); +} +FX_BYTE CFX_GEFont::GetCharSet() const +{ + FXSYS_assert(m_pFont != NULL); + if (m_wCharSet != 0xFFFF) { + return (FX_BYTE)m_wCharSet; + } + if (m_pFont->m_pSubstFont == NULL) { + return FX_CHARSET_Default; + } + return m_pFont->m_pSubstFont->m_Charset; +} +void CFX_GEFont::GetFamilyName(CFX_WideString &wsFamily) const +{ + FXSYS_assert(m_pFont != NULL); + if (m_pFont->m_pSubstFont == NULL || m_pFont->m_pSubstFont->m_Family.GetLength() == 0) { + wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName()); + } else { + wsFamily = CFX_WideString::FromLocal(m_pFont->m_pSubstFont->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->m_pSubstFont == NULL) { + if (m_pFont->IsBold()) { + dwStyles |= FX_FONTSTYLE_Bold; + } + if (m_pFont->IsItalic()) { + dwStyles |= FX_FONTSTYLE_Italic; + } + } else { + if (m_pFont->m_pSubstFont->m_Weight == FXFONT_FW_BOLD) { + dwStyles |= FX_FONTSTYLE_Bold; + } + if (m_pFont->m_pSubstFont->m_SubstFlags & FXFONT_SUBST_ITALIC) { + dwStyles |= FX_FONTSTYLE_Italic; + } + } + return dwStyles; +} +FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode) +{ + return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode); +} +FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &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; + FX_INT32 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, (FX_SHORT)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); + FX_LPVOID pRect = NULL; + if (!m_pBBoxMap->Lookup((void*)(FX_UINTPTR)wUnicode, pRect)) { + IFX_Font *pFont = NULL; + FX_INT32 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()); + FX_INT32 index = m_pRectArray->Add(rt); + pRect = m_pRectArray->GetPtrAt(index); + m_pBBoxMap->SetAt((void*)(FX_UINTPTR)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; +} +FX_INT32 CFX_GEFont::GetItalicAngle() const +{ + if (m_pFont->m_pSubstFont == NULL) { + return 0; + } + return m_pFont->m_pSubstFont->m_ItalicAngle; +} +FX_INT32 CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) +{ + return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode); +} +FX_INT32 CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode) +{ + FXSYS_assert (m_pFontEncoding != NULL); + FX_INT32 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*)(FX_UINTPTR)wUnicode, (void*&)pFont); + if (pFont != NULL && pFont != (IFX_Font*)this) { + iGlyphIndex = ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode); + if (iGlyphIndex != 0xFFFF) { + FX_INT32 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(), (FX_LPCWSTR)wsFamily); +#else + IFX_Font *pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), (FX_LPCWSTR)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*)(FX_UINTPTR)wUnicode, (void*)pFont); + FX_INT32 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; +} +FX_INT32 CFX_GEFont::GetAscent() const +{ + return m_pFont->GetAscent(); +} +FX_INT32 CFX_GEFont::GetDescent() const +{ + return m_pFont->GetDescent(); +} +void CFX_GEFont::Reset() +{ + Lock(); + FX_INT32 iCount = m_SubstFonts.GetSize(); + for (FX_INT32 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(FX_INT32 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 new file mode 100644 index 0000000000..430ff09852 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_gefont.h @@ -0,0 +1,81 @@ +// 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_Object +{ +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(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage); + FX_BOOL LoadFont(FX_LPCBYTE pBuffer, FX_INT32 length); + FX_BOOL LoadFont(FX_LPCWSTR 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 FX_BYTE GetCharSet() const; + virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE); + virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE); + virtual FX_INT32 GetAscent() const; + virtual FX_INT32 GetDescent() const; + virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE); + virtual FX_BOOL GetBBox(CFX_Rect &bbox); + virtual FX_INT32 GetItalicAngle() const; + virtual void Reset(); + virtual IFX_Font* GetSubstFont(FX_INT32 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; + FX_INT32 m_iRefCount; + FX_BOOL m_bExtFont; + IFX_Stream *m_pStream; + IFX_FileRead *m_pFileRead; + IFX_FontEncoding *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; + void InitFont(); + FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE); + FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE); + FX_INT32 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 new file mode 100644 index 0000000000..ae59cab2e5 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp @@ -0,0 +1,1490 @@ +// 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 "../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 , FX_LPVOID pUserData ) +{ + return FX_NEW CFX_StdFontMgrImp(pEnumerator, pMatcher, pUserData); +} +CFX_StdFontMgrImp::CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher, FX_LPVOID 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 (FX_INT32 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, FX_LPCWSTR pszFontFamily) +{ + FX_DWORD dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); + IFX_Font *pFont = NULL; + if (m_CPFonts.Lookup((void*)(FX_UINTPTR)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*)(FX_UINTPTR)dwHash, (void*)pFont); + dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage); + m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + return LoadFont(pFont, dwFontStyles, wCodePage); + } + return NULL; +} +IFX_Font* CFX_StdFontMgrImp::GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily) +{ + return GetDefFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles, pszFontFamily); +} +#define _FX_USEGASFONTMGR_ +IFX_Font* CFX_StdFontMgrImp::GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR 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*)(FX_UINTPTR)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); + FX_LPCWSTR 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; + } + FX_INT32 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 = FX_NEW CFX_Font; + if (pFXFont == NULL) { + return NULL; + } + 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(); + FX_LPCWSTR pFontFace = wsPsName; +#endif + if (pFont != NULL) { + m_Fonts.Add(pFont); + m_UnicodeFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); + m_CPFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage); + m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + return LoadFont(pFont, dwFontStyles, wCodePage); + } + return NULL; +} +IFX_Font* CFX_StdFontMgrImp::GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily) +{ + return GetDefFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_StdFontMgrImp::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage) +{ + FX_DWORD dwHash = FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage); + IFX_Font *pFont = NULL; + if (m_FamilyFonts.Lookup((void*)(FX_UINTPTR)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*)(FX_UINTPTR)dwHash, (void*)pFont); + dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles); + m_CPFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + return LoadFont(pFont, dwFontStyles, wCodePage); + } + return NULL; +} +IFX_Font* CFX_StdFontMgrImp::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 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(FX_LPCWSTR pszFileName) +{ + FXSYS_assert(pszFileName != NULL); + FX_DWORD dwHash = FX_HashCode_String_GetW(pszFileName, -1); + IFX_Font *pFont = NULL; + if (m_FileFonts.Lookup((void*)(FX_UINTPTR)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*)(FX_UINTPTR)dwHash, (void*)pFont); + return pFont->Retain(); + } + return NULL; +} +IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR 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*)(FX_UINTPTR)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*)(FX_UINTPTR)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*)(FX_UINTPTR)dwFontStyles, (void*)(FX_UINTPTR)wCodePage}; + FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)buffer, 3 * sizeof(void*)); + IFX_Font *pFont = NULL; + if (m_DeriveFonts.GetCount() > 0) { + m_DeriveFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont); + if (pFont != NULL) { + return pFont->Retain(); + } + } + pFont = pSrcFont->Derive(dwFontStyles, wCodePage); + if (pFont != NULL) { + m_DeriveFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont); + FX_INT32 index = m_Fonts.Find(pFont); + if (index < 0) { + m_Fonts.Add(pFont); + pFont->Retain(); + } + return pFont; + } + return NULL; +} +void CFX_StdFontMgrImp::ClearFontCache() +{ + FX_INT32 iCount = m_Fonts.GetSize(); + for (FX_INT32 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(); + FX_LPVOID pKey; + FX_LPVOID 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); + FX_INT32 iFind = m_Fonts.Find(pFont); + if (iFind > -1) { + m_Fonts.RemoveAt(iFind, 1); + } +} +FX_LPCFONTDESCRIPTOR CFX_StdFontMgrImp::FindFont(FX_LPCWSTR 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 (FX_INT32 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, FX_LPVOID pUserData) +{ + FX_LPCFONTDESCRIPTOR pBestFont = NULL; + FX_INT32 iBestSimilar = 0; + FX_BOOL bMatchStyle = (pParams->dwMatchFlags & FX_FONTMATCHPARA_MacthStyle) > 0; + FX_INT32 iCount = fonts.GetSize(); + for (FX_INT32 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; + } + } + FX_INT32 iSimilarValue = FX_GetSimilarValue(pFont, pParams->dwFontStyles); + if (iBestSimilar < iSimilarValue) { + iBestSimilar = iSimilarValue; + pBestFont = pFont; + } + } + return iBestSimilar < 1 ? NULL : pBestFont; +} +FX_INT32 FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles) +{ + FX_INT32 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; + } + FX_BYTE 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 FX_INT32 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); + if (NULL == pFont) { + return 0; + } + FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR)); + pFont->uCharSet = lf.lfCharSet; + pFont->dwFontStyles = FX_GetGdiFontStyles(lf); + FXSYS_wcsncpy(pFont->wsFontFace, (FX_LPCWSTR)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, FX_LPVOID pUserData, FX_LPCWSTR 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_LPWSTR)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 +FX_LPCSTR g_FontFolders[] = { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ + (FX_LPCSTR)"/usr/share/fonts", + (FX_LPCSTR)"/usr/share/X11/fonts/Type1", + (FX_LPCSTR)"/usr/share/X11/fonts/TTF", + (FX_LPCSTR)"/usr/local/share/fonts", +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + (FX_LPCSTR)"~/Library/Fonts", + (FX_LPCSTR)"/Library/Fonts", + (FX_LPCSTR)"/System/Library/Fonts", +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ + (FX_LPCSTR)"/system/fonts", +#endif +}; +CFX_FontSourceEnum_File::CFX_FontSourceEnum_File() +{ + for (FX_INT32 i = 0; i < sizeof(g_FontFolders) / sizeof(FX_LPCSTR); i++) { + m_FolderPaths.Add(g_FontFolders[i]); + } +} +CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() +{ +Restart: + FX_LPVOID 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( FX_LPVOID 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, FX_LPVOID 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*)FX_NEW CFX_FontSourceEnum_File; +} +IFX_FontMgr* IFX_FontMgr::Create(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate, FX_LPVOID pUserData) +{ + if (NULL == pFontEnum) { + return NULL; + } + CFX_FontMgrImp* pFontMgr = FX_NEW CFX_FontMgrImp(pFontEnum, pDelegate, pUserData); + if (NULL == pFontMgr) { + return NULL; + } + if (pFontMgr->EnumFonts()) { + return pFontMgr; + } + delete pFontMgr; + return NULL; +} +CFX_FontMgrImp::CFX_FontMgrImp( IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate , FX_LPVOID pUserData ) + : m_pFontSource(pFontEnum) + , m_pDelegate(pDelegate) + , m_pUserData(pUserData) +{ +} +FX_BOOL CFX_FontMgrImp::EnumFonts() +{ + FXFT_Library& library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; + if (library == NULL) { + FXFT_Init_FreeType(&library); + } + if (library == NULL) { + return FALSE; + } + FXFT_Face pFace = NULL; + FX_POSITION pos = m_pFontSource->GetStartPosition(); + IFX_FileAccess* pFontSource = NULL; + IFX_FileRead* pFontStream = NULL; + while (pos) { + pFontSource = m_pFontSource->GetNext(pos); + pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly); + if (NULL == pFontStream) { + pFontSource->Release(); + continue; + } + if (NULL == (pFace = LoadFace(pFontStream, 0))) { + pFontStream->Release(); + pFontSource->Release(); + continue; + } + FX_INT32 nFaceCount = pFace->num_faces; + ReportFace(pFace, m_InstalledFonts, pFontSource); + if (FXFT_Get_Face_External_Stream(pFace)) { + FXFT_Clear_Face_External_Stream(pFace); + } + FXFT_Done_Face(pFace); + for (FX_INT32 i = 1; i < nFaceCount; i++) { + if (NULL == (pFace = LoadFace(pFontStream, i))) { + continue; + } + ReportFace(pFace, m_InstalledFonts, pFontSource); + if (FXFT_Get_Face_External_Stream(pFace)) { + FXFT_Clear_Face_External_Stream(pFace); + } + FXFT_Done_Face(pFace); + } + pFontStream->Release(); + pFontSource->Release(); + } + return TRUE; +} +void CFX_FontMgrImp::Release() +{ + for (FX_INT32 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* 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, FX_LPCWSTR pszFontFamily ) +{ + return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCodePage(this, wCodePage, dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::GetDefFontByCharset( FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily ) +{ + return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCharset(this, nCharset, dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::GetDefFontByUnicode( FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily ) +{ + return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByUnicode(this, wUnicode, dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::GetDefFontByLanguage( FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily ) +{ + return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByLanguage(this, wLanguage, dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::GetFontByCodePage( FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR 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* 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 (NULL == pFonts) { + pFonts = FX_NEW CFX_ArrayTemplate; + } + if (NULL == pFonts) { + return NULL; + } + m_Hash2Fonts.SetAt(dwHash, pFonts); + CFX_FontDescriptorInfos* sortedFonts = NULL; + if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { + sortedFonts = FX_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; + pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, NULL); + if (NULL != pFont) { + pFont->SetLogicalFontStyle(dwFontStyles); + } + pFonts->Add(pFont); + return pFont; +} +IFX_Font* CFX_FontMgrImp::GetFontByCharset( FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily ) +{ + return GetFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::GetFontByUnicode( FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily ) +{ + IFX_Font* pFont = NULL; + if (m_FailedUnicodes2NULL.Lookup(wUnicode, pFont)) { + return NULL; + } + FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wUnicode); + FX_WORD wCodePage = NULL == x ? 0xFFFF : x->wCodePage; + FX_WORD wBitField = NULL == x ? 999 : x->wBitField; + 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* pFonts = NULL; + if (m_Hash2Fonts.Lookup(dwHash, pFonts)) { + if (NULL == pFonts) { + return NULL; + } + if (0 != pFonts->GetSize()) { + for (FX_INT32 i = 0; i < pFonts->GetSize(); i++) { + if (VerifyUnicode(pFonts->GetAt(i), wUnicode)) { + return pFonts->GetAt(i)->Retain(); + } + } + } + } + if (NULL == pFonts) { + pFonts = FX_NEW CFX_ArrayTemplate; + } + if (NULL == pFonts) { + return NULL; + } + m_Hash2Fonts.SetAt(dwHash, pFonts); + CFX_FontDescriptorInfos* sortedFonts = NULL; + if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) { + sortedFonts = FX_NEW CFX_FontDescriptorInfos; + MatchFonts(*sortedFonts, wCodePage, dwFontStyles, CFX_WideString(pszFontFamily), wUnicode); + m_Hash2CandidateList.SetAt(dwHash, sortedFonts); + } + for (FX_INT32 i = 0; i < sortedFonts->GetSize(); i++) { + CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont; + if (VerifyUnicode(pDesc, wUnicode)) { + pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, NULL); + if (NULL != pFont) { + pFont->SetLogicalFontStyle(dwFontStyles); + } + pFonts->Add(pFont); + return pFont; + } + } + if (NULL == pszFontFamily) { + m_FailedUnicodes2NULL.SetAt(wUnicode, NULL); + } + return NULL; +} +FX_BOOL CFX_FontMgrImp::VerifyUnicode( CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode ) +{ + IFX_FileRead* pFileRead = pDesc->m_pFileAccess->CreateFileStream(FX_FILEMODE_ReadOnly); + if (NULL == pFileRead) { + return FALSE; + } + FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex); + if (NULL == pFace) { + goto BadRet; + } + if (0 != FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE)) { + goto BadRet; + } + if (0 == FXFT_Get_Char_Index(pFace, wcUnicode)) { + goto BadRet; + } + pFileRead->Release(); + if (FXFT_Get_Face_External_Stream(pFace)) { + FXFT_Clear_Face_External_Stream(pFace); + } + FXFT_Done_Face(pFace); + return TRUE; +BadRet: + if (NULL != pFileRead) { + pFileRead->Release(); + } + if (NULL != pFace) { + if (FXFT_Get_Face_External_Stream(pFace)) { + FXFT_Clear_Face_External_Stream(pFace); + } + FXFT_Done_Face(pFace); + } + return FALSE; +} +FX_BOOL CFX_FontMgrImp::VerifyUnicode( IFX_Font* pFont, FX_WCHAR wcUnicode ) +{ + if (NULL == pFont) { + return FALSE; + } + FXFT_Face pFace = ((CFX_Font*)pFont->GetDevFont())->m_Face; + 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, FX_LPCWSTR pszFontFamily ) +{ + return GetFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles, pszFontFamily); +} +IFX_Font* CFX_FontMgrImp::LoadFont( FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount ) +{ + FX_LPVOID Hash[2] = {(FX_LPVOID)(FX_UINTPTR)pBuffer, (FX_LPVOID)(FX_UINTPTR)iLength}; + FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)Hash, 2 * sizeof (FX_LPVOID)); + 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( FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount ) +{ + CFX_ByteString bsHash; + bsHash += CFX_WideString(pszFileName).UTF8Encode(); + FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)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, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bSaveStream ) +{ + FX_LPVOID Hash[1] = {(FX_LPVOID)(FX_UINTPTR)pFontStream}; + FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)Hash, 1 * sizeof (FX_LPVOID)); + 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, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bWantCache ) +{ + FX_DWORD dwHash = 0; + IFX_Font* pFont = NULL; + if (bWantCache) { + CFX_ByteString bsHash; + bsHash.Format("%d, %d", (FX_UINTPTR)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())->m_Face->num_faces; + } + return pFont->Retain(); + } + } + } + CFX_Font* pInternalFont = FX_NEW CFX_Font; + if (NULL == pInternalFont) { + return NULL; + } + 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())->m_Face->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, FX_INT32 iFaceIndex ) +{ + FXFT_Library& library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; + FXFT_Open_Args ftArgs; + FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1); + FXFT_Face pFace = NULL; + if (library == NULL) { + FXFT_Init_FreeType(&library); + } + if (library == NULL) { + goto BadRet; + } + FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args)); + if (NULL == ftStream) { + goto BadRet; + } + FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec)); + if (NULL == pFontStream) { + goto BadRet; + } + ftStream->base = NULL; + ftStream->descriptor.pointer = pFontStream; + ftStream->pos = 0; + ftStream->size = (unsigned long)pFontStream->GetSize(); + ftStream->read = _ftStreamRead; + ftStream->close = _ftStreamClose; + ftArgs.flags |= FT_OPEN_STREAM; + ftArgs.stream = ftStream; + if (0 != FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) { + goto BadRet; + } + FXFT_Set_Pixel_Sizes(pFace, 0, 64); + return pFace; +BadRet: + if (NULL != ftStream) { + FX_Free(ftStream); + } + return NULL; +} +FX_INT32 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; + NormalizeFontName(wsNormalizedFontName); + static const FX_INT32 nMax = 0xffff; + CFX_FontDescriptor* pFont = NULL; + FX_INT32 nCount = m_InstalledFonts.GetSize(); + for (FX_INT32 i = 0; i < nCount; i++) { + pFont = m_InstalledFonts[i]; + FX_INT32 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 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 (FX_INT32 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; +} +FX_INT32 CFX_FontMgrImp::CalcPenalty( CFX_FontDescriptor* pInstalled, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode ) +{ + FX_INT32 nPenalty = 30000; + if (0 != FontName.GetLength()) { + if (FontName != pInstalled->m_wsFaceName) { + FX_INT32 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)) { + FX_INT32 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* pFonts; + m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts); + if (NULL != pFonts) { + for (FX_INT32 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 = FX_NEW CFX_FontDescriptor; + if (NULL == pFont) { + return; + } + 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; + FX_LPBYTE 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(FX_BYTE, nLength); + if (NULL != pTable) { + 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; + pFont->m_pFileAccess = pFontAccess->Retain(); + NormalizeFontName(pFont->m_wsFaceName); + for (FX_INT32 i = 0; i < pFont->m_wsFamilyNames.GetSize(); i++) { + NormalizeFontName(pFont->m_wsFamilyNames[i]); + } + Fonts.Add(pFont); +} +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) { + FX_BYTE uSerif = pOS2->panose[1]; + if ((uSerif > 1 && uSerif < 10) || uSerif > 13) { + flag |= FX_FONTSTYLE_Serif; + } + } + return flag; +} +#define GetUInt8(p) ((FX_UINT8)((p)[0])) +#define GetUInt16(p) ((FX_UINT16)((p)[0] << 8 | (p)[1])) +#define GetUInt32(p) ((FX_UINT32)((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])) +void CFX_FontMgrImp::GetNames(FX_LPCBYTE name_table, CFX_WideStringArray& Names) +{ + if (NULL == name_table) { + return; + } + FX_LPBYTE lpTable = (FX_LPBYTE)name_table; + CFX_WideString wsFamily; + FX_LPBYTE sp = lpTable + 2; + FX_LPBYTE lpNameRecord = lpTable + 6; + FX_UINT16 nNameCount = GetUInt16(sp); + FX_LPBYTE lpStr = lpTable + GetUInt16(sp + 2); + for (FX_UINT16 j = 0; j < nNameCount; j++) { + FX_UINT16 nNameID = GetUInt16(lpNameRecord + j * 12 + 6); + if (nNameID != 1) { + continue; + } + FX_UINT16 nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0); + FX_UINT16 nNameLength = GetUInt16(lpNameRecord + j * 12 + 8); + FX_UINT16 nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10); + wsFamily.Empty(); + if (nPlatformID != 1) { + for (FX_UINT16 k = 0; k < nNameLength / 2; k++) { + FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2); + wsFamily += wcTemp; + } + Names.Add(wsFamily); + } else { + for (FX_UINT16 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 (FX_INT32 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; + } +} +void CFX_FontMgrImp::NormalizeFontName( CFX_WideString& FontName ) +{ + FontName.MakeLower(); + FontName.Remove(' '); + FontName.Remove('-'); +} +FX_INT32 CFX_FontMgrImp::IsPartName( const CFX_WideString& Name1, const CFX_WideString& Name2 ) +{ + if (Name1.Find((FX_LPCWSTR)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 new file mode 100644 index 0000000000..adcc737ca5 --- /dev/null +++ b/xfa/src/fgas/src/font/fx_stdfontmgr.h @@ -0,0 +1,175 @@ +// 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_ +FX_INT32 FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles); +FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams, const CFX_FontDescriptors &fonts, FX_LPVOID pUserData); +class CFX_StdFontMgrImp : public IFX_FontMgr, public CFX_Object +{ +public: + CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher, FX_LPVOID pUserData); + ~CFX_StdFontMgrImp(); + virtual void Release() + { + delete this; + } + virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF); + virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength); + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName); + virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR 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; + FX_LPVOID m_pUserData; + void RemoveFont(CFX_MapPtrToPtr &fontMap, IFX_Font *pFont); + FX_LPCFONTDESCRIPTOR FindFont(FX_LPCWSTR 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_Object +{ +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; + FX_INT32 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_FontDescriptors; +struct FX_FontDescriptorInfo { +public: + CFX_FontDescriptor* pFont; + FX_INT32 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 CFX_FontDescriptorInfos; +struct FX_HandleParentPath : public CFX_Object { + 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_Object +{ +public: + CFX_FontSourceEnum_File(); + virtual void Release() + { + delete this; + }; + virtual FX_POSITION GetStartPosition(FX_LPVOID pUserData = NULL); + virtual IFX_FileAccess* GetNext(FX_POSITION& pos, FX_LPVOID pUserData = NULL); +private: + CFX_ByteString GetNextFile(); + CFX_WideString m_wsNext; + CFX_ObjectArray m_FolderQueue; + CFX_ByteStringArray m_FolderPaths; +}; +typedef CFX_MapPtrTemplate CFX_HashFileMap; +typedef CFX_MapPtrTemplate CFX_HashFontMap; +typedef CFX_MapPtrTemplate CFX_HashFontDescsMap; +typedef CFX_MapPtrTemplate* > CFX_HashFontsMap; +typedef CFX_MapPtrTemplate CFX_UnicodeFontMap; +typedef CFX_MapPtrTemplate* > CFX_FileFontMap; +typedef CFX_MapPtrTemplate CFX_FonStreamtMap; +class CFX_FontMgrImp : public IFX_FontMgr, public CFX_Object +{ +public: + CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate = NULL, FX_LPVOID pUserData = NULL); + virtual void Release(); + virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL); + virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount); + virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount); + virtual IFX_Font* LoadFont(IFX_Stream* pFontStream, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bSaveStream = FALSE); + virtual void ClearFontCache(); + virtual void RemoveFont(IFX_Font* pFont); + FX_BOOL EnumFonts(); +protected: + void ReportFace(FXFT_Face pFace, CFX_FontDescriptors& Fonts, IFX_FileAccess* pFontAccess); + void GetNames(FX_LPCBYTE 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); + void NormalizeFontName( CFX_WideString& FontName ); + FX_INT32 IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2); + FX_INT32 MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode = 0xFFFE); + FX_INT32 CalcPenalty(CFX_FontDescriptor* pInstalled, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode = 0xFFFE); + IFX_Font* LoadFont(IFX_FileAccess* pFontAccess, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bWantCache = FALSE); + FXFT_Face LoadFace(IFX_FileRead* pFontStream, FX_INT32 iFaceIndex); + 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; + FX_LPVOID m_pUserData; +}; +#endif +#endif diff --git a/xfa/src/fgas/src/layout/fx_linebreak.cpp b/xfa/src/fgas/src/layout/fx_linebreak.cpp new file mode 100644 index 0000000000..4662e1c122 --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_linebreak.cpp @@ -0,0 +1,121 @@ +// 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 "../fgas_base.h" +extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536]; +extern 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(FX_LPCWSTR pwsText, FX_LINEBREAKTYPE *pBrkType, FX_INT32 iLength) +{ + if (iLength < 2) { + return; + } + FX_DWORD dwCur, dwNext; + FX_WCHAR wch; + wch = *pwsText ++; + dwCur = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F; + iLength --; + for (FX_INT32 i = 0; i < iLength; i ++) { + wch = *pwsText ++; + dwNext = gs_FX_TextLayout_CodeProperties[(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(FX_LPCWSTR pwsText, FX_INT32 iLength, CFX_Int32MassArray &bp) +{ + if (iLength < 2) { + return; + } + FX_LINEBREAKTYPE eType; + FX_DWORD dwCur, dwNext; + FX_WCHAR wch; + wch = *pwsText ++; + dwCur = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F; + iLength --; + for (FX_INT32 i = 0; i < iLength; i ++) { + wch = *pwsText ++; + dwNext = gs_FX_TextLayout_CodeProperties[(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 new file mode 100644 index 0000000000..24c64c453b --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_rtfbreak.cpp @@ -0,0 +1,1522 @@ +// 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 "../fgas_base.h" +#include "fx_unicode.h" +#include "fx_rtfbreak.h" +extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536]; +extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64]; +extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512]; +extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32]; +IFX_RTFBreak* IFX_RTFBreak::Create(FX_DWORD dwPolicies) +{ + return FX_NEW CFX_RTFBreak(dwPolicies); +} +CFX_RTFBreak::CFX_RTFBreak(FX_DWORD dwPolicies) + : m_dwPolicies(dwPolicies) + , m_pArabicChar(NULL) + , m_iLineStart(0) + , m_iLineEnd(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::SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) +{ + m_iLineStart = FXSYS_round(fLineStart * 20000.0f); + m_iLineEnd = FXSYS_round(fLineEnd * 20000.0f); + FXSYS_assert(m_iLineEnd >= m_iLineStart); + if (m_pCurLine->m_iStart < m_iLineStart) { + m_pCurLine->m_iStart = m_iLineStart; + } +} +void CFX_RTFBreak::SetLinePos(FX_FLOAT fLinePos) +{ + FX_INT32 iLinePos = FXSYS_round(fLinePos * 20000.0f); + if (iLinePos > m_iLineEnd) { + iLinePos = m_iLineEnd; + } + 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) +{ + FX_INT32 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) +{ + FX_INT32 iLineEnd = m_iLineEnd; + FX_INT32 iTabPos = FXSYS_round(fTabPos * 20000.0f) + m_iLineStart; + if (iTabPos > iLineEnd) { + iTabPos = iLineEnd; + } + if (m_PositionedTabs.Find(iTabPos, 0) > -1) { + return; + } + FX_INT32 iCount = m_PositionedTabs.GetSize(); + FX_INT32 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(); + FX_INT32 iCount = tabs.GetSize(); + m_PositionedTabs.SetSize(iCount); + FX_INT32 iLineEnd = m_iLineEnd; + FX_INT32 iTabPos; + for (FX_INT32 i = 0; i < iCount; i ++) { + iTabPos = FXSYS_round(tabs[i] * 20000.0f) + m_iLineStart; + 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(FX_INT32 iScale) +{ + if (iScale < 0) { + iScale = 0; + } + if (m_iHorizontalScale == iScale) { + return; + } + SetBreakStatus(); + m_iHorizontalScale = iScale; +} +void CFX_RTFBreak::SetVerticalScale(FX_INT32 iScale) +{ + if (iScale < 0) { + iScale = 0; + } + if (m_iVerticalScale == iScale) { + return; + } + SetBreakStatus(); + m_iVerticalScale = iScale; +} +void CFX_RTFBreak::SetCharRotation(FX_INT32 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(FX_INT32 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 FX_INT32 gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2}; +FX_INT32 CFX_RTFBreak::GetLineRotation(FX_DWORD dwStyles) const +{ + return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1]; +} +void CFX_RTFBreak::SetBreakStatus() +{ + m_dwIdentity ++; + FX_INT32 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(FX_INT32 index) const +{ + CFX_RTFCharArray &tca = m_pCurLine->m_LineChars; + FX_INT32 iCount = tca.GetSize(); + if (index < 0 || index >= iCount) { + return NULL; + } + CFX_RTFChar *pTC; + FX_INT32 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; +} +FX_INT32 CFX_RTFBreak::GetLastPositionedTab() const +{ + FX_INT32 iCount = m_PositionedTabs.GetSize(); + if (iCount < 1) { + return m_iLineStart; + } + return m_PositionedTabs[iCount - 1]; +} +FX_BOOL CFX_RTFBreak::GetPositionedTab(FX_INT32 &iTabPos) const +{ + FX_INT32 iCount = m_PositionedTabs.GetSize(); + for (FX_INT32 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, FX_INT32 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 = gs_FX_TextLayout_CodeProperties[(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_iLineEnd + m_iTolerance) { + if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) { + dwRet1 = EndBreak(FX_RTFBREAK_LineBreak); + FX_INT32 iCount = m_pCurLine->CountChars(); + if (iCount > 0) { + pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1); + } + } + } + } + FX_INT32 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 FX_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; + FX_INT32 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_iLineEnd + m_iTolerance) { + return EndBreak(FX_RTFBREAK_LineBreak); + } + return FX_RTFBREAK_None; +} +FX_DWORD CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar *pCurChar, FX_INT32 iRotation) +{ + FX_INT32 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, FX_INT32 iRotation) +{ + if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab) { + FX_BOOL bBreak = FALSE; + if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) { + bBreak = (m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance); + } + FX_INT32 &iLineWidth = m_pCurLine->m_iWidth; + FX_INT32 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, FX_INT32 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, FX_INT32 iRotation) +{ + CFX_RTFChar *pLastChar = NULL; + FX_INT32 &iLineWidth = m_pCurLine->m_iWidth; + FX_INT32 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); + FX_INT32 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_iLineEnd + m_iTolerance) { + return EndBreak(FX_RTFBREAK_LineBreak); + } + return FX_RTFBREAK_None; +} +FX_DWORD CFX_RTFBreak::AppendChar_Others(CFX_RTFChar *pCurChar, FX_INT32 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; + } + FX_INT32 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_iLineEnd + 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; + FX_INT32 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_iLineStart; + 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_iLineEnd + 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; + FX_INT32 iLast = m_pCurLine->CountChars() - 1, j = 0; + for (FX_INT32 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) { + FX_INT32 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; + FX_INT32 i, j; + CFX_RTFCharArray &chars = m_pCurLine->m_LineChars; + FX_INT32 iCount = m_pCurLine->CountChars(); + FX_BOOL bDone = (!m_bPagination && !m_bCharCode && (m_pCurLine->m_iArabicChars > 0 || m_bRTL)); + if (bDone) { + FX_INT32 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; + FX_INT32 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); + FX_INT32 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; + FX_INT32 iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth; + FX_INT32 iCount = pCurPieces->GetSize(); + FX_BOOL bFind = FALSE; + FX_DWORD dwCharType; + FX_INT32 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; + } + } + FX_INT32 iOffset = m_iLineEnd - iNetWidth; + FX_INT32 iLowerAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_LowerMask); + FX_INT32 iHigherAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_HigherMask); + if (iGapChars > 0 && (iHigherAlignment == FX_RTFLINEALIGNMENT_Distributed || (iHigherAlignment == FX_RTFLINEALIGNMENT_Justified && dwStatus != FX_RTFBREAK_ParagraphBreak))) { + FX_INT32 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; + } + FX_INT32 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; + } + } + } +} +FX_INT32 CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray &tca, FX_INT32 &iEndPos, FX_BOOL bAllChars, FX_BOOL bOnlyBrk) +{ + FX_INT32 iLength = tca.GetSize() - 1; + if (iLength < 1) { + return iLength; + } + FX_INT32 iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1, iLast = -1, iLastPos = -1; + if (m_bSingleLine || m_bOrphanLine || iEndPos <= m_iLineEnd) { + if (!bAllChars || m_bCharCode) { + return iLength; + } + iBreak = iLength; + iBreakPos = iEndPos; + } + CFX_RTFChar *pCharArray = tca.GetData(); + if (m_bCharCode) { + const CFX_RTFChar *pChar; + FX_INT32 iCharWidth; + while (iLength > 0) { + if (iEndPos <= m_iLineEnd) { + 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; + FX_INT32 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_iLineEnd; + } else { + bBreak = iEndPos <= m_iLineEnd; + } + 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); + FX_INT32 iCount = pCurLine->CountChars(); + if (iCount < 2) { + return; + } + FX_INT32 iEndPos = pCurLine->GetLineEnd(); + CFX_RTFCharArray &curChars = pCurLine->m_LineChars; + FX_INT32 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 (FX_INT32 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; + } +} +FX_INT32 CFX_RTFBreak::CountBreakPieces() const +{ + CFX_RTFPieceArray *pRTFPieces = GetRTFPieces(TRUE); + if (pRTFPieces == NULL) { + return 0; + } + return pRTFPieces->GetSize(); +} +const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(FX_INT32 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_iLineStart) / 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; + FX_INT32 iCount = rtfPieces.GetSize(); + if (iCount < 1) { + rect.width = 0; + return; + } + CFX_RTFPiece *pBreakPiece; + FX_INT32 iLineHeight = 0, iMax; + for (FX_INT32 i = 0; i < iCount; i ++) { + pBreakPiece = rtfPieces.GetPtrAt(i); + FX_INT32 iFontHeight = FXSYS_round(pBreakPiece->m_iFontHeight * pBreakPiece->m_iVerticalScale / 100.0f); + iMax = FX_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); +} +FX_INT32 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); + FX_LPCWSTR pStr = pText->pStr; + FX_INT32 *pWidths = pText->pWidths; + FX_INT32 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; + FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f); + FX_INT32 iAscent = pFont->GetAscent(); + FX_INT32 iDescent = pFont->GetDescent(); + FX_INT32 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; + FX_INT32 iRotation = GetLineRotation(dwStyles) + pText->iCharRotation; + FX_INT32 iCharRotation; + FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm; + FX_INT32 iWidth, iCharWidth, iCharHeight; + FX_FLOAT fX, fY, fCharWidth, fCharHeight; + FX_INT32 iHorScale = pText->iHorizontalScale; + FX_INT32 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; + } + FX_INT32 iCount = 0; + for (FX_INT32 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; +} +FX_INT32 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); + FX_LPCWSTR pStr = pText->pStr; + FX_INT32 *pWidths = pText->pWidths; + FX_INT32 iLength = pText->iLength; + CFX_RectF rect(*pText->pRect); + FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel); + FX_FLOAT fFontSize = pText->fFontSize; + FX_INT32 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 = FX_MAX(0, 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 bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0; + FX_BOOL bSingleLine = (dwStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0; + FX_BOOL bCombText = (dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0; + FX_WCHAR wch, wLineBreakChar = pText->wLineBreakChar; + FX_INT32 iCharSize; + FX_FLOAT fCharSize, fStart; + if (bVertical) { + fStart = bRTLPiece ? rect.bottom() : rect.top; + } else { + fStart = bRTLPiece ? rect.right() : rect.left; + } + for (FX_INT32 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) { + FX_INT32 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 = FX_MAX(rtBBoxF.left, 0); + } else { + rtBBoxF.left = rect.left + fRTLeft; + rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f; + rtBBoxF.width = fCharWidth; + rtBBoxF.height = fHeight; + rtBBoxF.top = FX_MAX(rtBBoxF.top, 0); + } + 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 new file mode 100644 index 0000000000..bf5f1ee4b5 --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_rtfbreak.h @@ -0,0 +1,180 @@ +// 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 +class CFX_RTFLine; +class CFX_RTFBreak; +class CFX_RTFLine : public CFX_Object +{ +public: + CFX_RTFLine() : m_LinePieces(16) + , m_iStart(0) + , m_iWidth(0) + , m_iArabicChars(0) + , m_iMBCSChars(0) + { + } + ~CFX_RTFLine() + { + RemoveAll(); + } + FX_INT32 CountChars() const + { + return m_LineChars.GetSize(); + } + CFX_RTFChar& GetChar(FX_INT32 index) + { + FXSYS_assert(index > -1 && index < m_LineChars.GetSize()); + return *m_LineChars.GetDataPtr(index); + } + CFX_RTFChar* GetCharPtr(FX_INT32 index) + { + FXSYS_assert(index > -1 && index < m_LineChars.GetSize()); + return m_LineChars.GetDataPtr(index); + } + FX_INT32 CountPieces() const + { + return m_LinePieces.GetSize(); + } + CFX_RTFPiece& GetPiece(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_LinePieces.GetSize()); + return m_LinePieces.GetAt(index); + } + CFX_RTFPiece* GetPiecePtr(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_LinePieces.GetSize()); + return m_LinePieces.GetPtrAt(index); + } + FX_INT32 GetLineEnd() const + { + return m_iStart + m_iWidth; + } + void RemoveAll(FX_BOOL bLeaveMemory = FALSE) + { + CFX_RTFChar *pChar; + IFX_Unknown *pUnknown; + FX_INT32 iCount = m_LineChars.GetSize(); + for (FX_INT32 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; + FX_INT32 m_iStart; + FX_INT32 m_iWidth; + FX_INT32 m_iArabicChars; + FX_INT32 m_iMBCSChars; +}; +class CFX_RTFBreak : public IFX_RTFBreak, public CFX_Object +{ +public: + CFX_RTFBreak(FX_DWORD dwPolicies); + ~CFX_RTFBreak(); + virtual void Release() + { + delete this; + } + virtual void SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd); + 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); + virtual void AddPositionedTab(FX_FLOAT fTabPos); + virtual void SetPositionedTabs(const CFX_FloatArray &tabs); + virtual void ClearPositionedTabs(); + virtual void SetDefaultChar(FX_WCHAR wch); + virtual void SetLineBreakChar(FX_WCHAR wch); + virtual void SetLineBreakTolerance(FX_FLOAT fTolerance); + virtual void SetHorizontalScale(FX_INT32 iScale); + virtual void SetVerticalScale(FX_INT32 iScale); + virtual void SetCharRotation(FX_INT32 iCharRotation); + virtual void SetCharSpace(FX_FLOAT fCharSpace); + virtual void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace); + virtual void SetReadingOrder(FX_BOOL bRTL = FALSE); + virtual void SetAlignment(FX_INT32 iAlignment = FX_RTFLINEALIGNMENT_Left); + virtual void SetUserData(IFX_Unknown *pUserData); + virtual FX_DWORD AppendChar(FX_WCHAR wch); + virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak); + virtual FX_INT32 CountBreakPieces() const; + virtual const CFX_RTFPiece* GetBreakPiece(FX_INT32 index) const; + virtual void GetLineRect(CFX_RectF &rect) const; + virtual void ClearBreakPieces(); + virtual void Reset(); + virtual FX_INT32 GetDisplayPos(FX_LPCRTFTEXTOBJ pText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const; + virtual FX_INT32 GetCharRects(FX_LPCRTFTEXTOBJ pText, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const; + FX_DWORD AppendChar_CharCode(FX_WCHAR wch); + FX_DWORD AppendChar_Combination(CFX_RTFChar *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Tab(CFX_RTFChar *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Control(CFX_RTFChar *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Arabic(CFX_RTFChar *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Others(CFX_RTFChar *pCurChar, FX_INT32 iRotation); +protected: + FX_DWORD m_dwPolicies; + IFX_ArabicChar *m_pArabicChar; + FX_INT32 m_iLineStart; + FX_INT32 m_iLineEnd; + FX_DWORD m_dwLayoutStyles; + FX_BOOL m_bPagination; + FX_BOOL m_bVertical; + FX_BOOL m_bSingleLine; + FX_BOOL m_bCharCode; + IFX_Font *m_pFont; + FX_INT32 m_iFontHeight; + FX_INT32 m_iFontSize; + FX_INT32 m_iTabWidth; + CFX_Int32Array m_PositionedTabs; + FX_BOOL m_bOrphanLine; + FX_WCHAR m_wDefChar; + FX_INT32 m_iDefChar; + FX_WCHAR m_wLineBreakChar; + FX_INT32 m_iHorizontalScale; + FX_INT32 m_iVerticalScale; + FX_INT32 m_iLineRotation; + FX_INT32 m_iCharRotation; + FX_INT32 m_iRotation; + FX_INT32 m_iCharSpace; + FX_BOOL m_bWordSpace; + FX_INT32 m_iWordSpace; + FX_BOOL m_bRTL; + FX_INT32 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; + FX_INT32 m_iReady; + FX_INT32 m_iTolerance; + FX_INT32 GetLineRotation(FX_DWORD dwStyles) const; + void SetBreakStatus(); + CFX_RTFChar* GetLastChar(FX_INT32 index) const; + CFX_RTFLine* GetRTFLine(FX_BOOL bReady) const; + CFX_RTFPieceArray* GetRTFPieces(FX_BOOL bReady) const; + FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const; + FX_INT32 GetLastPositionedTab() const; + FX_BOOL GetPositionedTab(FX_INT32 &iTabPos) const; + FX_INT32 GetBreakPos(CFX_RTFCharArray &tca, FX_INT32 &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 new file mode 100644 index 0000000000..0bb7b69585 --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_textbreak.cpp @@ -0,0 +1,1653 @@ +// 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 "../fgas_base.h" +#include "fx_unicode.h" +#include "fx_textbreak.h" +extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536]; +extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64]; +extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512]; +extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32]; +IFX_TxtBreak* IFX_TxtBreak::Create(FX_DWORD dwPolicies) +{ + return FX_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 = FX_NEW CFX_TxtLine(sizeof(CFX_Char)); + m_pTxtLine2 = FX_NEW CFX_TxtLine(sizeof(CFX_Char)); + } else { + m_pTxtLine1 = FX_NEW CFX_TxtLine(sizeof(CFX_TxtChar)); + m_pTxtLine2 = FX_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) +{ + FX_INT32 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) +{ + FX_INT32 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(FX_INT32 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(FX_INT32 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(FX_LPVOID pUserData) +{ + if (m_pUserData == pUserData) { + return; + } + SetBreakStatus(); + m_pUserData = pUserData; +} +void CFX_TxtBreak::SetBreakStatus() +{ + if (m_bPagination) { + return; + } + FX_INT32 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(FX_INT32 iScale) +{ + if (iScale < 0) { + iScale = 0; + } + if (iScale == m_iHorScale) { + return; + } + SetBreakStatus(); + m_iHorScale = iScale; +} +void CFX_TxtBreak::SetVerticalScale(FX_INT32 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 FX_INT32 gs_FX_TxtLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2}; +FX_INT32 CFX_TxtBreak::GetLineRotation(FX_DWORD dwStyles) const +{ + return gs_FX_TxtLineRotations[(dwStyles & 0x0E) >> 1]; +} +CFX_TxtChar* CFX_TxtBreak::GetLastChar(FX_INT32 index, FX_BOOL bOmitChar) const +{ + CFX_TxtCharArray &ca = *m_pCurLine->m_pLineChars; + FX_INT32 iCount = ca.GetSize(); + if (index < 0 || index >= iCount) { + return NULL; + } + CFX_TxtChar *pTC; + FX_INT32 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) { + FX_INT32 iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS; + FX_INT32 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, FX_INT32 iRotation) +{ + FXSYS_assert(pCurChar != NULL); + FX_WCHAR wch = pCurChar->m_wCharCode; + FX_WCHAR wForm; + FX_INT32 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, FX_INT32 iRotation) +{ + m_dwCharType = FX_CHARTYPE_Tab; + if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) { + return FX_TXTBREAK_None; + } + FX_INT32 &iLineWidth = m_pCurLine->m_iWidth; + FX_INT32 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, FX_INT32 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, FX_INT32 iRotation) +{ + FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK); + FX_INT32 &iLineWidth = m_pCurLine->m_iWidth; + FX_WCHAR wForm; + FX_INT32 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); + FX_INT32 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, FX_INT32 iRotation) +{ + FX_DWORD dwProps = pCurChar->m_dwCharProps; + FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK); + FX_INT32 &iLineWidth = m_pCurLine->m_iWidth; + FX_INT32 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, FX_INT32 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 = gs_FX_TextLayout_CodeProperties[(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); + FX_INT32 iCount = m_pCurLine->CountChars(); + if (iCount > 0) { + pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1); + } + } + } + } + FX_INT32 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 FX_MAX(dwRet1, dwRet2); +} +void CFX_TxtBreak::EndBreak_UpdateArabicShapes() +{ + FXSYS_assert(m_bArabicShapes); + FX_INT32 iCount = m_pCurLine->CountChars(); + if (iCount < 2) { + return; + } + FX_INT32 &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; + FX_INT32 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) +{ + FX_INT32 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) { + FX_INT32 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; + FX_INT32 i, j; + CFX_TxtCharArray &chars = *m_pCurLine->m_pLineChars; + FX_INT32 iCount = m_pCurLine->CountChars(); + FX_BOOL bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL); + if (!m_bPagination && bDone) { + FX_INT32 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; + FX_INT32 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); + FX_INT32 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) +{ + FX_INT32 iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth; + CFX_TxtPieceArray *pCurPieces = m_pCurLine->m_pLinePieces; + FX_INT32 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; + } + } + FX_INT32 iOffset = m_iLineWidth - iNetWidth; + FX_INT32 iLowerAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_LowerMask); + FX_INT32 iHigherAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_HigherMask); + if (iGapChars > 0 && (iHigherAlignment == FX_TXTLINEALIGNMENT_Distributed || (iHigherAlignment == FX_TXTLINEALIGNMENT_Justified && dwStatus != FX_TXTBREAK_ParagraphBreak))) { + FX_INT32 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; + } + FX_INT32 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; + FX_INT32 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; +} +FX_INT32 CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray &ca, FX_INT32 &iEndPos, FX_BOOL bAllChars, FX_BOOL bOnlyBrk) +{ + FX_INT32 iLength = ca.GetSize() - 1; + if (iLength < 1) { + return iLength; + } + FX_INT32 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; + FX_INT32 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 = (FX_BYTE)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); + FX_INT32 iCount = pCurLine->CountChars(); + if (iCount < 2) { + return; + } + FX_INT32 iEndPos = pCurLine->m_iWidth; + CFX_TxtCharArray &curChars = *pCurLine->m_pLineChars; + FX_INT32 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(); + FX_INT32 iCharWidth, iWidth = 0; + for (FX_INT32 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; +} +FX_INT32 CFX_TxtBreak::CountBreakChars() const +{ + CFX_TxtLine *pTxtLine = GetTxtLine(TRUE); + return pTxtLine == NULL ? 0 : pTxtLine->CountChars(); +} +FX_INT32 CFX_TxtBreak::CountBreakPieces() const +{ + CFX_TxtPieceArray *pTxtPieces = GetTxtPieces(TRUE); + if (pTxtPieces == NULL) { + return 0; + } + return pTxtPieces->GetSize(); +} +const CFX_TxtPiece* CFX_TxtBreak::GetBreakPiece(FX_INT32 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; + FX_INT32 iWidth; +} FX_FORMCHAR, * FX_LPFORMCHAR; +typedef FX_FORMCHAR const * FX_LPCFORMCHAR; +FX_INT32 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; + FX_LPVOID pIdentity = pTxtRun->pIdentity; + FX_LPCWSTR pStr = pTxtRun->pStr; + FX_INT32 *pWidths = pTxtRun->pWidths; + FX_INT32 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; + FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f); + FX_INT32 iAscent = pFont->GetAscent(); + FX_INT32 iDescent = pFont->GetDescent(); + FX_INT32 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; + FX_INT32 iRotation = GetLineRotation(dwStyles) + pTxtRun->iCharRotation; + FX_INT32 iCharRotation; + FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm, wLast = 0xFEFF; + FX_INT32 iWidth, iCharWidth, iCharHeight; + FX_FLOAT fX, fY, fCharWidth, fCharHeight; + FX_INT32 iHorScale = pTxtRun->iHorizontalScale; + FX_INT32 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; + } + FX_INT32 iCount = 0, iNext, iForms; + for (FX_INT32 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 { + FX_INT32 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 (FX_INT32 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) { + FX_INT32 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; +} +FX_INT32 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; + FX_LPVOID pIdentity = pTxtRun->pIdentity; + FX_LPCWSTR pStr = pTxtRun->pStr; + FX_INT32 *pWidths = pTxtRun->pWidths; + FX_INT32 iLength = pTxtRun->iLength; + CFX_RectF rect(*pTxtRun->pRect); + FX_BOOL bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0; + FX_FLOAT fFontSize = pTxtRun->fFontSize; + FX_INT32 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 = FX_MAX(0, 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; + FX_INT32 iCharSize; + FX_FLOAT fCharSize, fStart; + if (bVertical) { + fStart = bRTLPiece ? rect.bottom() : rect.top; + } else { + fStart = bRTLPiece ? rect.right() : rect.left; + } + for (FX_INT32 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) { + FX_INT32 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 = FX_MAX(rtBBoxF.left, 0); + } else { + rtBBoxF.left = rect.left + fRTLeft; + rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f; + rtBBoxF.width = fCharWidth; + rtBBoxF.height = fHeight; + rtBBoxF.top = FX_MAX(rtBBoxF.top, 0); + } + 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 new file mode 100644 index 0000000000..c5bbc40946 --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_textbreak.h @@ -0,0 +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 +class CFX_TxtLine; +class CFX_Txtbreak; +class CFX_TxtLine : public CFX_Object +{ +public: + CFX_TxtLine(FX_INT32 iBlockSize) : m_iStart(0) + , m_iWidth(0) + , m_iArabicChars(0) + { + m_pLineChars = FX_NEW CFX_TxtCharArray; + m_pLinePieces = FXTARGET_New CFX_TxtPieceArray(16); + } + ~CFX_TxtLine() + { + RemoveAll(); + delete m_pLineChars; + FXTARGET_Delete m_pLinePieces; + } + FX_INT32 CountChars() const + { + return m_pLineChars->GetSize(); + } + CFX_TxtChar* GetCharPtr(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_pLineChars->GetSize()); + return m_pLineChars->GetDataPtr(index); + } + FX_INT32 CountPieces() const + { + return m_pLinePieces->GetSize(); + } + CFX_TxtPiece* GetPiecePtr(FX_INT32 index) const + { + FXSYS_assert(index > -1 && index < m_pLinePieces->GetSize()); + return m_pLinePieces->GetPtrAt(index); + } + void GetString(CFX_WideString &wsStr) const + { + FX_INT32 iCount = m_pLineChars->GetSize(); + FX_LPWSTR pBuf = wsStr.GetBuffer(iCount); + CFX_Char *pChar; + for (FX_INT32 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; + FX_INT32 m_iStart; + FX_INT32 m_iWidth; + FX_INT32 m_iArabicChars; +}; +class CFX_TxtBreak : public IFX_TxtBreak, public CFX_Object +{ +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(FX_INT32 iScale); + virtual void SetVerticalScale(FX_INT32 iScale); + virtual void SetCharRotation(FX_INT32 iCharRotation); + virtual void SetCharSpace(FX_FLOAT fCharSpace); + virtual void SetAlignment(FX_INT32 iAlignment); + virtual FX_DWORD GetContextCharStyles() const; + virtual void SetContextCharStyles(FX_DWORD dwCharStyles); + virtual void SetCombWidth(FX_FLOAT fCombWidth); + virtual void SetUserData(FX_LPVOID pUserData); + virtual FX_DWORD AppendChar(FX_WCHAR wch); + virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak); + virtual FX_INT32 CountBreakChars() const; + virtual FX_INT32 CountBreakPieces() const; + virtual const CFX_TxtPiece* GetBreakPiece(FX_INT32 index) const; + virtual void ClearBreakPieces(); + virtual void Reset(); + virtual FX_INT32 GetDisplayPos(FX_LPCTXTRUN pTxtRun, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const; + virtual FX_INT32 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, FX_INT32 iRotation); + FX_DWORD AppendChar_Tab(CFX_Char *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Control(CFX_Char *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Arabic(CFX_Char *pCurChar, FX_INT32 iRotation); + FX_DWORD AppendChar_Others(CFX_Char *pCurChar, FX_INT32 iRotation); +protected: + FX_DWORD m_dwPolicies; + FX_BOOL m_bPagination; + IFX_ArabicChar *m_pArabicChar; + FX_INT32 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; + FX_INT32 m_iArabicContext; + FX_INT32 m_iCurArabicContext; + IFX_Font *m_pFont; + FX_INT32 m_iFontSize; + FX_BOOL m_bEquidistant; + FX_INT32 m_iTabWidth; + FX_WCHAR m_wDefChar; + FX_WCHAR m_wParagBreakChar; + FX_INT32 m_iDefChar; + FX_INT32 m_iLineRotation; + FX_INT32 m_iCharRotation; + FX_INT32 m_iRotation; + FX_INT32 m_iAlignment; + FX_DWORD m_dwContextCharStyles; + FX_INT32 m_iCombWidth; + FX_LPVOID m_pUserData; + FX_DWORD m_dwCharType; + FX_BOOL m_bCurRTL; + FX_INT32 m_iCurAlignment; + FX_BOOL m_bArabicNumber; + FX_BOOL m_bArabicComma; + CFX_TxtLine *m_pTxtLine1; + CFX_TxtLine *m_pTxtLine2; + CFX_TxtLine *m_pCurLine; + FX_INT32 m_iReady; + FX_INT32 m_iTolerance; + FX_INT32 m_iHorScale; + FX_INT32 m_iVerScale; + FX_INT32 m_iCharSpace; + void SetBreakStatus(); + FX_INT32 GetLineRotation(FX_DWORD dwStyles) const; + CFX_TxtChar* GetLastChar(FX_INT32 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); + FX_INT32 GetBreakPos(CFX_TxtCharArray &ca, FX_INT32 &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 new file mode 100644 index 0000000000..def5d707f5 --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_unicode.cpp @@ -0,0 +1,146 @@ +// 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 "../fgas_base.h" +#include "fx_unicode.h" +void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray &tpos, FX_INT32 iStart, FX_INT32 iEnd) +{ + FXSYS_assert(iStart > -1 && iStart < tpos.GetSize()); + FXSYS_assert(iEnd > -1 && iEnd < tpos.GetSize()); + if (iStart >= iEnd) { + return; + } + FX_INT32 i = iStart, j = iEnd; + FX_TPO *pCur = tpos.GetPtrAt(iStart), *pSort; + FX_INT32 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) +{ + FX_INT32 iStart = 0; + FX_INT32 iEnd = sizeof(gs_FX_JapCharPropertysEx) / sizeof(FX_JAPCHARPROPERTYEX); + while (iStart <= iEnd) { + FX_INT32 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 new file mode 100644 index 0000000000..5eadb5506f --- /dev/null +++ b/xfa/src/fgas/src/layout/fx_unicode.h @@ -0,0 +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 { + FX_INT32 index; + FX_INT32 pos; +} FX_TPO; +typedef CFX_MassArrayTemplate CFX_TPOArray; +void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray &tpos, FX_INT32 iStart, FX_INT32 iEnd); +#endif diff --git a/xfa/src/fgas/src/localization/fx_datetime.cpp b/xfa/src/fgas/src/localization/fx_datetime.cpp new file mode 100644 index 0000000000..03ecb5bf48 --- /dev/null +++ b/xfa/src/fgas/src/localization/fx_datetime.cpp @@ -0,0 +1,548 @@ +// 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 "../fgas_base.h" +const FX_BYTE g_FXDaysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +const FX_BYTE g_FXDaysPerLeapMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +const FX_INT32 g_FXDaysBeforeMonth[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +const FX_INT32 g_FXDaysBeforeLeapMonth[12] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; +const FX_INT32 g_FXDaysPerYear = 365; +const FX_INT32 g_FXDaysPerLeapYear = 366; +const FX_INT32 g_FXDaysPer4Years = 1461; +const FX_INT32 g_FXDaysPer100Years = 36524; +const FX_INT32 g_FXDaysPer400Years = 146097; +const FX_INT64 g_FXMillisecondsPerSecond = 1000; +const FX_INT64 g_FXMillisecondsPerMinute = 60000; +const FX_INT64 g_FXMillisecondsPerHour = 3600000; +const FX_INT64 g_FXMillisecondsPerDay = 86400000; +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_ +const FX_INT64 g_FXMillisecondsPerYear = 0x0757B12C00; +const FX_INT64 g_FXMillisecondsPerLeapYear = 0x075CD78800; +const FX_INT64 g_FXMillisecondsPer4Years = 0x1D63EB0C00; +const FX_INT64 g_FXMillisecondsPer100Years = 0x02DEBCCDD000; +const FX_INT64 g_FXMillisecondsPer400Years = 0x0B7AF85D9C00; +#endif +FX_BOOL FX_IsLeapYear(FX_INT32 iYear) +{ + FXSYS_assert(iYear != 0); + return ((iYear % 4) == 0 && (iYear % 100) != 0) || (iYear % 400) == 0; +} +FX_INT32 FX_DaysInYear(FX_INT32 iYear) +{ + FXSYS_assert(iYear != 0); + return FX_IsLeapYear(iYear) ? g_FXDaysPerLeapYear : g_FXDaysPerYear; +} +FX_BYTE FX_DaysInMonth(FX_INT32 iYear, FX_BYTE iMonth) +{ + FXSYS_assert(iYear != 0); + FXSYS_assert(iMonth >= 1 && iMonth <= 12); + const FX_BYTE *p = FX_IsLeapYear(iYear) ? g_FXDaysPerLeapMonth : g_FXDaysPerMonth; + return p[iMonth - 1]; +} +static FX_INT32 FX_DaysBeforeMonthInYear(FX_INT32 iYear, FX_BYTE iMonth) +{ + FXSYS_assert(iYear != 0); + FXSYS_assert(iMonth >= 1 && iMonth <= 12); + const FX_INT32 *p = FX_IsLeapYear(iYear) ? g_FXDaysBeforeLeapMonth : g_FXDaysBeforeMonth; + return p[iMonth - 1]; +} +static FX_INT64 FX_DateToDays(FX_INT32 iYear, FX_BYTE iMonth, FX_BYTE iDay, FX_BOOL bIncludeThisDay = FALSE) +{ + FXSYS_assert(iYear != 0); + FXSYS_assert(iMonth >= 1 && iMonth <= 12); + FXSYS_assert(iDay >= 1 && iDay <= FX_DaysInMonth(iYear, iMonth)); + FX_INT64 iDays = FX_DaysBeforeMonthInYear(iYear, iMonth); + iDays += iDay; + if (!bIncludeThisDay) { + iDays --; + } + if (iYear > 0) { + iYear --; + } else { + iDays -= FX_DaysInYear(iYear); + iYear ++; + } + return iDays + (FX_INT64)iYear * 365 + iYear / 4 - iYear / 100 + iYear / 400; +} +static void FX_DaysToDate(FX_INT64 iDays, FX_INT32 &iYear, FX_BYTE &iMonth, FX_BYTE &iDay) +{ + FX_BOOL bBC = iDays < 0; + if (bBC) { + iDays = -iDays; + } + iYear = 1; + iMonth = 1; + iDay = 1; + if (iDays >= g_FXDaysPer400Years) { + iYear += (FX_INT32)(iDays / g_FXDaysPer400Years * 400); + iDays %= g_FXDaysPer400Years; + } + if (iDays >= g_FXDaysPer100Years) { + if (iDays == g_FXDaysPer100Years * 4) { + iYear += 300; + iDays -= g_FXDaysPer100Years * 3; + } else { + iYear += (FX_INT32)(iDays / g_FXDaysPer100Years * 100); + iDays %= g_FXDaysPer100Years; + } + } + if (iDays >= g_FXDaysPer4Years) { + iYear += (FX_INT32)(iDays / g_FXDaysPer4Years * 4); + iDays %= g_FXDaysPer4Years; + } + while (TRUE) { + FX_INT32 iYearDays = FX_DaysInYear(iYear); + if (iDays < iYearDays) { + if (bBC) { + iYear = -iYear; + iDays = iYearDays - iDays; + } + break; + } + iYear ++; + iDays -= iYearDays; + } + while (TRUE) { + FX_INT32 iMonthDays = FX_DaysInMonth(iYear, iMonth); + if (iDays < iMonthDays) { + break; + } + iMonth ++; + iDays -= iMonthDays; + } + iDay += (FX_BYTE)iDays; +} +#if _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_EMBEDDED_ || _FX_OS_ == _FX_ANDROID_ || _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ +#include +#include +#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, (FX_BYTE)utLocal.wMonth, (FX_BYTE)utLocal.wDay, + (FX_BYTE)utLocal.wHour, (FX_BYTE)utLocal.wMinute, (FX_BYTE)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, (FX_BYTE)utLocal.wMonth, (FX_BYTE)utLocal.wDay, + (FX_BYTE)utLocal.wHour, (FX_BYTE)utLocal.wMinute, (FX_BYTE)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds); +} +void CFX_Unitime::Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour, FX_BYTE minute, FX_BYTE second, FX_WORD millisecond) +{ + FXSYS_assert(hour <= 23); + FXSYS_assert(minute <= 59); + FXSYS_assert(second <= 59); + FXSYS_assert(millisecond <= 999); + m_iUnitime = (FX_INT64)hour * g_FXMillisecondsPerHour + (FX_INT64)minute * g_FXMillisecondsPerMinute + (FX_INT64)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; +} +FX_INT32 CFX_Unitime::GetYear() const +{ + FX_INT32 iYear; + FX_BYTE iMonth, iDay; + FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay); + return iYear; +} +FX_BYTE CFX_Unitime::GetMonth() const +{ + FX_INT32 iYear; + FX_BYTE iMonth, iDay; + FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay); + return iMonth; +} +FX_BYTE CFX_Unitime::GetDay() const +{ + FX_INT32 iYear; + FX_BYTE iMonth, iDay; + FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay); + return iDay; +} +FX_WEEKDAY CFX_Unitime::GetDayOfWeek() const +{ + FX_INT32 v = (FX_INT32)((m_iUnitime / g_FXMillisecondsPerDay + 1) % 7); + if (v < 0) { + v += 7; + } + return (FX_WEEKDAY)v; +} +FX_WORD CFX_Unitime::GetDayOfYear() const +{ + FX_INT32 iYear; + FX_BYTE iMonth, iDay; + FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay); + return FX_DaysBeforeMonthInYear(iYear, iMonth) + iDay; +} +FX_INT64 CFX_Unitime::GetDayOfAD() const +{ + FX_BOOL bBC = m_iUnitime < 0; + FX_INT64 iDays = m_iUnitime / g_FXMillisecondsPerDay; + iDays += bBC ? -1 : 0; + if (bBC && (m_iUnitime % g_FXMillisecondsPerDay) == 0) { + iDays ++; + } + return iDays; +} +FX_BYTE CFX_Unitime::GetHour() const +{ + FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerDay); + if (v < 0) { + v += g_FXMillisecondsPerDay; + } + return (FX_BYTE)(v / g_FXMillisecondsPerHour); +} +FX_BYTE CFX_Unitime::GetMinute() const +{ + FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerHour); + if (v < 0) { + v += g_FXMillisecondsPerHour; + } + return (FX_BYTE)(v / g_FXMillisecondsPerMinute); +} +FX_BYTE CFX_Unitime::GetSecond() const +{ + FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerMinute); + if (v < 0) { + v += g_FXMillisecondsPerMinute; + } + return (FX_BYTE)(v / g_FXMillisecondsPerSecond); +} +FX_WORD CFX_Unitime::GetMillisecond() const +{ + FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerSecond); + if (v < 0) { + v += g_FXMillisecondsPerSecond; + } + return (FX_WORD)v; +} +FX_BOOL CFX_Unitime::AddYears(FX_INT32 iYears) +{ + FX_UNITIME ut = m_iUnitime; + if (ut < 0) { + ut = -ut; + } + FX_UNITIME r = ut % g_FXMillisecondsPerDay; + FX_INT32 iYear; + FX_BYTE 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(FX_INT32 iMonths) +{ + FX_BOOL b = iMonths > 0; + FX_UNITIME ut = m_iUnitime; + if (ut < 0) { + ut = -ut; + } + FX_UNITIME r = ut % g_FXMillisecondsPerDay; + FX_INT32 iYear; + FX_BYTE 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, (FX_BYTE)iMonths, iDay, FALSE) * g_FXMillisecondsPerDay; + m_iUnitime += (iYear < 0) ? -r : r; + return TRUE; +} +FX_BOOL CFX_Unitime::AddDays(FX_INT32 iDays) +{ + m_iUnitime += (FX_INT64)iDays * g_FXMillisecondsPerDay; + return TRUE; +} +FX_BOOL CFX_Unitime::AddHours(FX_INT32 iHours) +{ + m_iUnitime += (FX_INT64)iHours * g_FXMillisecondsPerHour; + return TRUE; +} +FX_BOOL CFX_Unitime::AddMinutes(FX_INT32 iMinutes) +{ + m_iUnitime += (FX_INT64)iMinutes * g_FXMillisecondsPerMinute; + return TRUE; +} +FX_BOOL CFX_Unitime::AddSeconds(FX_INT32 iSeconds) +{ + m_iUnitime += ((FX_INT64)iSeconds) * g_FXMillisecondsPerSecond; + return TRUE; +} +FX_BOOL CFX_Unitime::AddMilliseconds(FX_INT32 iMilliseconds) +{ + m_iUnitime += iMilliseconds; + return TRUE; +} +FX_BOOL CFX_DateTime::Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour, FX_BYTE minute, FX_BYTE 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 = (FX_INT64)m_DateTime.Date.sDate.day * g_FXMillisecondsPerHour + (FX_INT64)m_DateTime.Time.sTime.minute * g_FXMillisecondsPerMinute + (FX_INT64)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; +} +FX_INT32 CFX_DateTime::GetYear() const +{ + return m_DateTime.Date.sDate.year; +} +FX_BYTE CFX_DateTime::GetMonth() const +{ + return m_DateTime.Date.sDate.month; +} +FX_BYTE CFX_DateTime::GetDay() const +{ + return m_DateTime.Date.sDate.day; +} +FX_WEEKDAY CFX_DateTime::GetDayOfWeek() const +{ + FX_INT32 v = (FX_INT32)(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; +} +FX_INT64 CFX_DateTime::GetDayOfAD() const +{ + return FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, TRUE); +} +FX_BYTE CFX_DateTime::GetHour() const +{ + return m_DateTime.Date.sDate.day; +} +FX_BYTE CFX_DateTime::GetMinute() const +{ + return m_DateTime.Time.sTime.minute; +} +FX_BYTE 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(FX_INT32 iYears) +{ + if (iYears == 0) { + return FALSE; + } + FX_INT32 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(FX_INT32 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 = (FX_BYTE)iMonths; + return TRUE; +} +FX_BOOL CFX_DateTime::AddDays(FX_INT32 iDays) +{ + if (iDays == 0) { + return FALSE; + } + FX_INT64 v1 = FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, TRUE); + FX_INT64 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(FX_INT32 iHours) +{ + if (iHours == 0) { + return FALSE; + } + iHours += m_DateTime.Date.sDate.day; + FX_INT32 iDays = iHours / 24; + iHours %= 24; + if (iHours < 0) { + iDays --, iHours += 24; + } + m_DateTime.Date.sDate.day = (FX_BYTE)iHours; + if (iDays != 0) { + AddDays(iDays); + } + return TRUE; +} +FX_BOOL CFX_DateTime::AddMinutes(FX_INT32 iMinutes) +{ + if (iMinutes == 0) { + return FALSE; + } + iMinutes += m_DateTime.Time.sTime.minute; + FX_INT32 iHours = iMinutes / 60; + iMinutes %= 60; + if (iMinutes < 0) { + iHours --, iMinutes += 60; + } + m_DateTime.Time.sTime.minute = (FX_BYTE)iMinutes; + if (iHours != 0) { + AddHours(iHours); + } + return TRUE; +} +FX_BOOL CFX_DateTime::AddSeconds(FX_INT32 iSeconds) +{ + if (iSeconds == 0) { + return FALSE; + } + iSeconds += m_DateTime.Time.sTime.second; + FX_INT32 iMinutes = iSeconds / 60; + iSeconds %= 60; + if (iSeconds < 0) { + iMinutes --, iSeconds += 60; + } + m_DateTime.Time.sTime.second = (FX_BYTE)iSeconds; + if (iMinutes != 0) { + AddMinutes(iMinutes); + } + return TRUE; +} +FX_BOOL CFX_DateTime::AddMilliseconds(FX_INT32 iMilliseconds) +{ + if (iMilliseconds == 0) { + return FALSE; + } + iMilliseconds += m_DateTime.Time.sTime.millisecond; + FX_INT32 iSeconds = (FX_INT32)(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 new file mode 100644 index 0000000000..a932a6c1a3 --- /dev/null +++ b/xfa/src/fgas/src/localization/fx_locale.cpp @@ -0,0 +1,4954 @@ +// 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 "../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 { + FX_UINT32 uHash; + FX_LPCWSTR pName; + FX_INT32 eSubCategory; +} FX_LOCALESUBCATEGORYINFO, * FX_LPLOCALESUBCATEGORYINFO; +typedef FX_LOCALESUBCATEGORYINFO const * FX_LPCLOCALESUBCATEGORYINFO; +const static FX_LOCALESUBCATEGORYINFO g_FXLocaleDateTimeSubCatData[] = { + {0x14da2125, (FX_LPCWSTR)L"default", FX_LOCALEDATETIMESUBCATEGORY_Default}, + {0x9041d4b0, (FX_LPCWSTR)L"short", FX_LOCALEDATETIMESUBCATEGORY_Short}, + {0xa084a381, (FX_LPCWSTR)L"medium", FX_LOCALEDATETIMESUBCATEGORY_Medium}, + {0xcdce56b3, (FX_LPCWSTR)L"full", FX_LOCALEDATETIMESUBCATEGORY_Full}, + {0xf6b4afb0, (FX_LPCWSTR)L"long", FX_LOCALEDATETIMESUBCATEGORY_Long}, +}; +const static FX_INT32 g_iFXLocaleDateTimeSubCatCount = sizeof(g_FXLocaleDateTimeSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO); +const static FX_LOCALESUBCATEGORYINFO g_FXLocaleNumSubCatData[] = { + {0x46f95531, (FX_LPCWSTR)L"percent", FX_LOCALENUMPATTERN_Percent}, + {0x4c4e8acb, (FX_LPCWSTR)L"currency", FX_LOCALENUMPATTERN_Currency}, + {0x54034c2f, (FX_LPCWSTR)L"decimal", FX_LOCALENUMPATTERN_Decimal}, + {0x7568e6ae, (FX_LPCWSTR)L"integer", FX_LOCALENUMPATTERN_Integer}, +}; +const static FX_INT32 g_iFXLocaleNumSubCatCount = sizeof(g_FXLocaleNumSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO); +typedef struct _FX_LOCALETIMEZONEINFO { + FX_DWORD uHash; + FX_INT16 iHour; + FX_INT16 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 FX_INT32 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(FX_WSTR wsSymbols, FX_WCHAR ch, FX_STRSIZE nStart = 0) +{ + FX_STRSIZE nLength = wsSymbols.GetLength(); + if (nLength < 1 || nStart > nLength) { + return -1; + } + FX_LPCWSTR lpsz = (FX_LPCWSTR)FXSYS_wcschr(wsSymbols.GetPtr() + nStart, ch); + return (lpsz == NULL) ? -1 : (FX_STRSIZE)(lpsz - wsSymbols.GetPtr()); +} +const static FX_LPCWSTR gs_LocalNumberSymbols[] = { + (FX_LPCWSTR)L"decimal", (FX_LPCWSTR)L"grouping", (FX_LPCWSTR)L"percent", (FX_LPCWSTR)L"minus", (FX_LPCWSTR)L"zero", + (FX_LPCWSTR)L"currencySymbol", (FX_LPCWSTR)L"currencyName", +}; +IFX_Locale* IFX_Locale::Create(CXML_Element* pLocaleData) +{ + return FX_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(FX_BSTR bsSpace, CXML_Element* pxmlElement, FX_BSTR bsTag, FX_WSTR wsName) +{ + CXML_Element* pDatePattern = NULL; + FX_INT32 nCount = pxmlElement->CountElements(bsSpace, bsTag); + FX_INT32 i = 0; + for (; i < nCount; i++) { + pDatePattern = pxmlElement->GetElement(bsSpace, bsTag, i); + if (pDatePattern->GetAttrValue(FX_BSTRC("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, FX_BSTRC("numberSymbols")); + if (!pNumberSymbols) { + return; + } + wsNumSymbol = FX_GetXMLContent(bsSpace, pNumberSymbols, FX_BSTRC("numberSymbol"), wsName); +} +void CFX_Locale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const +{ + if (!m_pElement) { + return; + } + CFX_ByteString bsSpace; + CXML_Element* pNumberSymbols = m_pElement->GetElement(bsSpace, FX_BSTRC("dateTimeSymbols")); + if (!pNumberSymbols) { + return; + } + wsDtSymbol = pNumberSymbols->GetContent(0); +} +static void FX_GetCalendarSymbol(CXML_Element* pXmlElement, const CFX_ByteString &symbol_type, FX_INT32 index, FX_BOOL bAbbr, CFX_WideString &wsName) +{ + CFX_ByteString bsSpace; + CFX_ByteString pstrSymbolNames = symbol_type + FX_BSTRC("Names"); + CXML_Element* pChild = pXmlElement->GetElement(bsSpace, FX_BSTRC("calendarSymbols")); + if (!pChild) { + return; + } + CXML_Element* pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames); + if (!pSymbolNames) { + return; + } + if (pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) != bAbbr) { + pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames, 1); + } + if (pSymbolNames && pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) == bAbbr) { + CXML_Element* pSymbolName = pSymbolNames->GetElement(bsSpace, symbol_type, index); + if (pSymbolName) { + wsName = pSymbolName->GetContent(0); + } + } +} +void CFX_Locale::GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr ) const +{ + if (!m_pElement) { + return; + } + FX_GetCalendarSymbol(m_pElement, "month", nMonth, bAbbr, wsMonthName); +} +void CFX_Locale::GetDayName(FX_INT32 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 FX_INT32 FX_ParseTimeZone(FX_LPCWSTR pStr, FX_INT32 iLen, FX_TIMEZONE& tz) +{ + tz.tzHour = 0; + tz.tzMinute = 0; + if (iLen < 0) { + return 0; + } + FX_INT32 iStart = 1; + FX_INT32 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("", FX_BSTRC("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 FX_INT32 gs_fraction_count = sizeof(gs_fraction_scales) / sizeof(FX_FLOAT); +class CFX_LCNumeric : public CFX_Object +{ +public: + CFX_LCNumeric(); + CFX_LCNumeric(FX_INT64 integral, FX_DWORD fractional = 0, FX_INT32 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(FX_INT32 nTreading, FX_BOOL bTrimTailZeros) const; + FX_INT64 m_Integral; + FX_DWORD m_Fractional; +#ifdef FX_NUM_DOUBLE + CFX_WideString m_wsValue; +#endif + FX_INT32 m_Exponent; +}; +static FX_BOOL FX_WStringToNumeric(const CFX_WideString& wsValue, CFX_LCNumeric& lcnum) +{ + FX_INT64 *pIntegral = &lcnum.m_Integral; + FX_DWORD *pFractional = &lcnum.m_Fractional; + FX_INT32 *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 FX_INT32 nIntegralMaxLen = 17; + FX_INT32 cc = 0; + FX_BOOL bNegative = FALSE, bExpSign = FALSE; + FX_LPCWSTR str = (FX_LPCWSTR)wsValue; + FX_INT32 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++; + } + FX_INT32 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(FX_INT64 integral, FX_DWORD fractional , FX_INT32 exponent ) +{ + m_Integral = integral; + m_Fractional = fractional; + m_Exponent = exponent; +} +CFX_LCNumeric::CFX_LCNumeric(FX_FLOAT dbRetValue) +{ + m_Integral = (FX_INT64)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 = (FX_INT64)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(FX_INT32 nTreading, FX_BOOL bTrimTailZeros) const +{ +#ifdef FX_NUM_DOUBLE + CFX_WideString wsResult; + if (!m_wsValue.IsEmpty()) { + const FX_INT32 nIntegralMaxLen = 17; + FX_INT32 cc = 0; + FX_BOOL bNegative = FALSE, bExpSign = FALSE; + FX_LPCWSTR str = (FX_LPCWSTR)m_wsValue; + FX_INT32 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++; + } + FX_INT32 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(); + FX_INT64 iInte = (FX_INT64)dbValeu; + wsResult.Format((FX_LPCWSTR)L"%l", (FX_INT64)iInte); + if (m_Fractional) { + CFX_WideString wsFormat; + wsFormat.Format((FX_LPCWSTR)L"%%.%dG", nTreading); + double dblMantissa = (dbValeu > 0) ? (dbValeu - iInte) : (iInte - dbValeu); + CFX_WideString wsFrac; + wsFrac.Format((FX_LPCWSTR)wsFormat, dblMantissa); + wsResult += CFX_WideStringC((FX_LPCWSTR)wsFrac + 1, wsFrac.GetLength() - 1); + if (bTrimTailZeros && nTreading > 0) { + wsResult.TrimRight(L"0"); + wsResult.TrimRight(L"."); + } + } +#endif + CFX_WideString wsFormat; + wsFormat.Format((FX_LPCWSTR)L"%%.%df", nTreading); + CFX_WideString wsResult; + wsResult.Format(FX_LPCWSTR(wsFormat), 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 FX_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) +{ + FX_INT32 iStrLen = wsFormatString.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsFormatString; + FX_LPCWSTR pToken = pStr; + FX_LPCWSTR 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(FX_LPCWSTR pStrPattern, FX_INT32 &iPattern, FX_INT32 iLenPattern) +{ + CFX_WideString wsOutput; + if (pStrPattern[iPattern] != '\'') { + return wsOutput; + } + iPattern++; + FX_INT32 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') { + FX_INT32 iKeyValue = 0; + iPattern += 2; + FX_INT32 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(FX_LPCWSTR pStrPattern, FX_INT32 &iPattern) +{ + CFX_WideString wsOutput; + if (pStrPattern[iPattern] != '\'') { + return wsOutput; + } + iPattern--; + FX_INT32 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--; + FX_INT32 iKeyValue = 0; + FX_INT32 iLen = wsOutput.GetLength(); + FX_INT32 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; + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsPattern.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)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(FX_LPCWSTR 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) +{ + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsPattern.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)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, FX_WSTR wsCategory, CFX_WideString& wsPurgePattern) +{ + IFX_Locale* pLocale = NULL; + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsPattern.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern; + FX_BOOL bBrackOpen = FALSE; + while (ccf < iLenf) { + if (pStr[ccf] == '\'') { + FX_INT32 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, FX_INT32& iDotIndex, FX_DWORD& dwStyle, CFX_WideString& wsPurgePattern) +{ + dwStyle = 0; + IFX_Locale* pLocale = NULL; + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsPattern.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern; + FX_BOOL bFindDot = FALSE; + FX_BOOL bBrackOpen = FALSE; + while (ccf < iLenf) { + if (pStr[ccf] == '\'') { + FX_INT32 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 (FX_INT32 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, FX_INT32 &iDotIndex) +{ + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsNum.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsNum; + FX_INT32 iLenDot = wsDotSymbol.GetLength(); + while (ccf < iLenf) { + if (pStr[ccf] == '\'') { + FX_GetLiteralText(pStr, ccf, iLenf); + } else if (ccf + iLenDot <= iLenf && !FXSYS_wcsncmp(pStr + ccf, (FX_LPCWSTR)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; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat); + if (wsTextFormat.IsEmpty()) { + return FALSE; + } + FX_INT32 iText = 0, iPattern = 0; + FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText; + FX_INT32 iLenText = wsSrcText.GetLength(); + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 iLenPattern = wsTextFormat.GetLength(); + while (iPattern < iLenPattern && iText < iLenText) { + switch (pStrPattern[iPattern]) { + case '\'': { + CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)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; + } + FX_INT32 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; + } + FX_INT32 iExponent = 0; + CFX_WideString wsDotSymbol; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol); + FX_INT32 iDotLen = wsDotSymbol.GetLength(); + CFX_WideString wsGroupSymbol; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol); + FX_INT32 iGroupLen = wsGroupSymbol.GetLength(); + CFX_WideString wsMinus; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus); + FX_INT32 iMinusLen = wsMinus.GetLength(); + int cc = 0, ccf = 0; + FX_LPCWSTR str = (FX_LPCWSTR)wsSrcNum; + int len = wsSrcNum.GetLength(); + FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat; + int lenf = wsNumFormat.GetLength(); + double dbRetValue = 0; + double coeff = 1; + FX_BOOL bHavePercentSymbol = FALSE; + FX_BOOL bNeg = FALSE; + FX_BOOL bReverseParse = FALSE; + FX_INT32 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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + cc -= iLiteralLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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, (FX_LPCWSTR)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), (FX_LPCWSTR)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); + FX_INT32 iSymbolLen = wsSymbol.GetLength(); + cc -= iSymbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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); + FX_INT32 iSysmbolLen = wsSymbol.GetLength(); + cc -= iSysmbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + cc -= iLiteralLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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, (FX_LPCWSTR)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), (FX_LPCWSTR)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); + FX_INT32 iSymbolLen = wsSymbol.GetLength(); + cc -= iSymbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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); + FX_INT32 iSysmbolLen = wsSymbol.GetLength(); + cc -= iSysmbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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, (FX_LPCWSTR)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); + FX_INT32 iSymbolLen = wsSymbol.GetLength(); + if (cc + iSymbolLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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); + FX_INT32 iSysmbolLen = wsSymbol.GetLength(); + if (cc + iSysmbolLen <= len && !FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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) +{ + FX_INT32 iCount = wsNum.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsNum; + FX_LPWSTR pDst = wsResult.GetBuffer(iCount); + FX_INT32 nIndex = 0; + FX_BOOL bMinus = FALSE; + FX_INT32 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'; + } + FX_INT32 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; + } + FX_INT32 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; + } + FX_INT32 iExponent = 0; + CFX_WideString wsDotSymbol; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol); + FX_INT32 iDotLen = wsDotSymbol.GetLength(); + CFX_WideString wsGroupSymbol; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol); + FX_INT32 iGroupLen = wsGroupSymbol.GetLength(); + CFX_WideString wsMinus; + pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus); + FX_INT32 iMinusLen = wsMinus.GetLength(); + int cc = 0, ccf = 0; + FX_LPCWSTR str = (FX_LPCWSTR)wsSrcNum; + int len = wsSrcNum.GetLength(); + FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat; + int lenf = wsNumFormat.GetLength(); + FX_BOOL bHavePercentSymbol = FALSE; + FX_BOOL bNeg = FALSE; + FX_BOOL bReverseParse = FALSE; + FX_INT32 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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + cc -= iLiteralLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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, (FX_LPCWSTR)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), (FX_LPCWSTR)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); + FX_INT32 iSymbolLen = wsSymbol.GetLength(); + cc -= iSymbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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); + FX_INT32 iSysmbolLen = wsSymbol.GetLength(); + cc -= iSysmbolLen - 1; + if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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, (FX_LPCWSTR)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); + FX_INT32 iSymbolLen = wsSymbol.GetLength(); + if (cc + iSymbolLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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); + FX_INT32 iSysmbolLen = wsSymbol.GetLength(); + if (cc + iSysmbolLen <= len && !FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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, (FX_LPCWSTR)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; + FX_INT32 ccf = 0; + FX_INT32 iLenf = wsPattern.GetLength(); + FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern; + FX_INT32 iFindCategory = 0; + FX_BOOL bBraceOpen = FALSE; + while (ccf < iLenf) { + if (pStr[ccf] == '\'') { + FX_INT32 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 (FX_INT32 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, FX_INT32 &cc) +{ + FX_INT32 year = 1900; + FX_INT32 month = 1; + FX_INT32 day = 1; + FX_INT32 ccf = 0; + FX_LPCWSTR str = (FX_LPCWSTR)wsDate; + FX_INT32 len = wsDate.GetLength(); + FX_LPCWSTR strf = (FX_LPCWSTR)wsDatePattern; + FX_INT32 lenf = wsDatePattern.GetLength(); + while (cc < len && ccf < lenf) { + if (strf[ccf] == '\'') { + CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)wsDayNameAbbr, str + cc, wsDayNameAbbr.GetLength())) { + break; + } + } + if (i < 12) { + cc += wsDayNameAbbr.GetLength(); + } + } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) { + CFX_WideString wsDayName; + FX_INT32 i = 0; + for (; i < 7; i++) { + pLocale->GetDayName(i, wsDayName, FALSE); + if (wsDayName == L"") { + continue; + } + if (!FXSYS_wcsncmp((FX_LPCWSTR)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; + } + } + CFX_Unitime ut; + ut.Set(year, month, day); + datetime = datetime + ut; + return cc; +} +static void FX_ResolveZone(FX_BYTE& wHour, FX_BYTE& wMinute, FX_TIMEZONE tzDiff, IFX_Locale* pLocale) +{ + FX_INT32 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, FX_INT32 &cc) +{ + FX_BYTE hour = 0; + FX_BYTE minute = 0; + FX_BYTE second = 0; + FX_WORD millisecond = 0; + FX_INT32 ccf = 0; + FX_LPCWSTR str = (FX_LPCWSTR)wsTime; + int len = wsTime.GetLength(); + FX_LPCWSTR strf = (FX_LPCWSTR)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); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)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; + FX_INT32 iStart = 0, iEnd = g_iFXLocaleTimeZoneCount - 1; + do { + FX_INT32 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) { + FX_INT32 iStart = 0; + if (!FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue, iStart)) { + return FALSE; + } + if (!FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue, iStart)) { + return FALSE; + } + } else { + FX_INT32 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; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat); + FX_INT32 iText = 0, iPattern = 0; + FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText; + FX_INT32 iLenText = wsSrcText.GetLength(); + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 iLenPattern = wsTextFormat.GetLength(); + while (iPattern < iLenPattern && iText < iLenText) { + if (pStrPattern[iPattern] == '\'') { + CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)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; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat); + FX_INT32 iText = 0, iPattern = 0; + FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText; + FX_INT32 iLenText = wsSrcText.GetLength(); + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 iLenPattern = wsTextFormat.GetLength(); + while (iPattern < iLenPattern && iText < iLenText) { + if (pStrPattern[iPattern] == '\'') { + CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern); + FX_INT32 iLiteralLen = wsLiteral.GetLength(); + if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)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; + } + FX_INT32 iLenText = wsSrcText.GetLength(); + if (iLenText == 0) { + return FALSE; + } + CFX_WideString wsTextFormat; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat); + FX_INT32 iText = 0, iPattern = 0; + FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText; + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 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 FX_INT32 FX_GetNumTrailingLimit(const CFX_WideString& wsFormat, int iDotPos, FX_BOOL &bTrimTailZeros) +{ + if (iDotPos < 0) { + return 0; + } + FX_INT32 iCount = wsFormat.GetLength(); + FX_INT32 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(FX_WSTR wsInputNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) +{ + if (wsInputNum.IsEmpty() || wsPattern.IsEmpty()) { + return FALSE; + } + FX_INT32 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; + } + FX_INT32 cc = 0, ccf = 0; + FX_LPCWSTR strf = (FX_LPCWSTR)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; + } + FX_INT32 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; + FX_INT32 iTreading = FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros); + FX_INT32 scale = decimal.GetScale(); + if (iTreading < scale) { + decimal.SetScale(iTreading); + wsSrcNum = decimal; + } + if (bTrimTailZeros && scale > 0 && iTreading > 0) { + wsSrcNum.TrimRight((FX_LPCWSTR)L"0"); + wsSrcNum.TrimRight((FX_LPCWSTR)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; + FX_LPCWSTR str = (FX_LPCWSTR)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((FX_LPCWSTR)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 (FX_INT32 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((FX_LPCWSTR)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) +{ + FX_INT32 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; + } + FX_INT32 cc = 0, ccf = 0; + FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat; + int lenf = wsNumFormat.GetLength(); + double dbOrgRaw = lcNum.GetDouble(); + double dbRetValue = dbOrgRaw; + if (dwNumStyle & FX_NUMSTYLE_Percent) { + dbRetValue *= 100; + } + FX_INT32 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; + FX_INT32 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; + FX_LPCWSTR str = (FX_LPCWSTR)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((FX_LPCWSTR)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 (FX_INT32 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((FX_LPCWSTR)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) +{ + FX_INT32 year = 1900; + FX_INT32 month = 1; + FX_INT32 day = 1; + FX_WORD wYear = 0; + int cc_start = 0, cc = 0; + FX_LPCWSTR str = (FX_LPCWSTR)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; + FX_BYTE 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++; + } + FX_BYTE 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(FX_WSTR wsTime, CFX_Unitime& datetime, IFX_Locale* pLocale) +{ + if (wsTime.GetLength() == 0) { + return FALSE; + } + FX_BYTE hour = 0; + FX_BYTE minute = 0; + FX_BYTE second = 0; + FX_WORD millisecond = 0; + int cc_start = 0, cc = cc_start; + FX_LPCWSTR str = (FX_LPCWSTR)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; + FX_INT32 year = datetime.GetYear(); + FX_BYTE month = datetime.GetMonth(); + FX_BYTE day = datetime.GetDay(); + FX_INT32 ccf = 0; + FX_LPCWSTR strf = (FX_LPCWSTR)wsDatePattern; + FX_INT32 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((FX_LPCWSTR)L"%d", day); + wsResult += wsDay; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) { + CFX_WideString wsDay; + wsDay.Format((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)L"%03d", nDays); + wsResult += wsDays; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) { + CFX_WideString wsMonth; + wsMonth.Format((FX_LPCWSTR)L"%d", month); + wsResult += wsMonth; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) { + CFX_WideString wsMonth; + wsMonth.Format((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)L"%02d", year % 100); + wsResult += wsYear; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) { + CFX_WideString wsYear; + wsYear.Format((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)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; + FX_BYTE hour = datetime.GetHour(); + FX_BYTE minute = datetime.GetMinute(); + FX_BYTE second = datetime.GetSecond(); + FX_WORD millisecond = datetime.GetMillisecond(); + FX_INT32 ccf = 0; + FX_LPCWSTR strf = (FX_LPCWSTR)wsTimePattern; + FX_INT32 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((FX_LPCWSTR)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((FX_LPCWSTR)L"%02d", wHour == 0 ? 12 : wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) { + CFX_WideString wsHour; + wsHour.Format((FX_LPCWSTR)L"%d", wHour == 0 ? 24 : wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) { + CFX_WideString wsHour; + wsHour.Format((FX_LPCWSTR)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((FX_LPCWSTR)L"%d", wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '1')) { + CFX_WideString wsHour; + wsHour.Format((FX_LPCWSTR)L"%d", wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2')) { + if (wHour > 12) { + wHour -= 12; + } + CFX_WideString wsHour; + wsHour.Format((FX_LPCWSTR)L"%02d", wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '2')) { + CFX_WideString wsHour; + wsHour.Format((FX_LPCWSTR)L"%02d", wHour); + wsResult += wsHour; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) { + CFX_WideString wsMinute; + wsMinute.Format((FX_LPCWSTR)L"%d", minute); + wsResult += wsMinute; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) { + CFX_WideString wsMinute; + wsMinute.Format((FX_LPCWSTR)L"%02d", minute); + wsResult += wsMinute; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) { + CFX_WideString wsSecond; + wsSecond.Format((FX_LPCWSTR)L"%d", second); + wsResult += wsSecond; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) { + CFX_WideString wsSecond; + wsSecond.Format((FX_LPCWSTR)L"%02d", second); + wsResult += wsSecond; + } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) { + CFX_WideString wsMilliseconds; + wsMilliseconds.Format((FX_LPCWSTR)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((FX_LPCWSTR)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((FX_LPCWSTR)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); + FX_INT32 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); + FX_INT32 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((FX_LPCWSTR)wsSrcDateTime, iT); + CFX_WideStringC wsSrcTime((FX_LPCWSTR)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; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat); + FX_INT32 iPattern = 0; + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 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; + IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat); + FX_INT32 iPattern = 0; + FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat; + FX_INT32 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(FX_WSTR 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) ((FX_UINT8)(((FLAGS) & ~FXMATH_DECIMAL_NEGMASK) >> 0x10)) +#define FXMATH_DECIMAL_RSHIFT32BIT(x) ((x)>>0x10>>0x10) +#define FXMATH_DECIMAL_LSHIFT32BIT(x) ((x)<<0x10<<0x10) +static inline FX_UINT8 fxmath_decimal_helper_div10(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo) +{ + FX_UINT8 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 FX_UINT8 fxmath_decimal_helper_div10_any(FX_UINT64 nums[], FX_UINT8 numcount) +{ + FX_UINT8 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(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo) +{ + plo *= 0xA; + pmid = pmid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(plo); + plo = (FX_UINT32)plo; + phi = phi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(pmid); + pmid = (FX_UINT32)pmid; +} +static inline void fxmath_decimal_helper_mul10_any(FX_UINT64 nums[], FX_UINT8 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] = (FX_UINT32)nums[i - 1]; + } +} +static inline void fxmath_decimal_helper_normalize(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo) +{ + phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid); + pmid = (FX_UINT32)pmid; + pmid += FXMATH_DECIMAL_RSHIFT32BIT(plo); + plo = (FX_UINT32)plo; + phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid); + pmid = (FX_UINT32)pmid; +} +static inline void fxmath_decimal_helper_normalize_any(FX_UINT64 nums[], FX_UINT8 len) +{ + { + for(int i = len - 2; i > 0; i --) { + nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]); + nums[i] = (FX_UINT32)nums[i]; + } + } + { + for(int i = 0; i < len - 1; i ++) { + nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]); + nums[i] = (FX_UINT32)nums[i]; + } + } +} +static inline FX_INT8 fxmath_decimal_helper_raw_compare(FX_UINT32 hi1, FX_UINT32 mid1, FX_UINT32 lo1, FX_UINT32 hi2, FX_UINT32 mid2, FX_UINT32 lo2) +{ + FX_INT8 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 FX_INT8 fxmath_decimal_helper_raw_compare_any(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl) +{ + FX_INT8 retVal = 0; + for(int i = FX_MAX(al - 1, bl - 1); i >= 0; i --) { + FX_UINT64 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(FX_UINT64 a[], FX_UINT8 al) +{ + for(int i = 0; i < al; i ++) { + if(a[i]--) { + return; + } + } +} +static inline void fxmath_decimal_helper_inc_any(FX_UINT64 a[], FX_UINT8 al) +{ + for(int i = 0; i < al; i ++) { + a[i]++; + if((FX_UINT32)a[i] == a[i]) { + return; + } + a[i] = 0; + } +} +static inline void fxmath_decimal_helper_raw_mul(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl, FX_UINT64 c[], FX_UINT8 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++) { + FX_UINT64 m = (FX_UINT64)a[i] * b[j]; + c[i + j] += (FX_UINT32)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] = (FX_UINT32)c[i]; + } + } + { + for(int i = 0; i < cl; i++) { + c[i] = (FX_UINT32)c[i]; + } + } +} +static inline void fxmath_decimal_helper_raw_div(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl, FX_UINT64 c[], FX_UINT8 cl) +{ + int i; + for(i = 0; i < cl; i++) { + c[i] = 0; + } + FX_UINT64 left[16] = {0}, right[16] = {0}; + left[0] = 0; + for(i = 0; i < al; i++) { + right[i] = a[i]; + } + FX_UINT64 tmp[16]; + while(fxmath_decimal_helper_raw_compare_any(left, al, right, al) <= 0) { + FX_UINT64 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 < FX_MIN(al, cl); i++) { + c[i] = cur[i]; + } + return; + } + } + for(i = 0; i < FX_MIN(al, cl); i++) { + c[i] = left[i]; + } +} +static inline FX_BOOL fxmath_decimal_helper_outofrange(FX_UINT64 a[], FX_UINT8 al, FX_UINT8 goal) +{ + for(int i = goal; i < al; i++) { + if(a[i]) { + return TRUE; + } + } + return FALSE; +} +static inline void fxmath_decimal_helper_shrinkintorange(FX_UINT64 a[], FX_UINT8 al, FX_UINT8 goal, FX_UINT8& 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(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo, FX_UINT8& scale, FX_UINT8 minscale = 0) +{ + while(scale > minscale) { + FX_UINT64 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(FX_UINT64 val) +{ + m_uLo = (FX_UINT32)val; + m_uMid = (FX_UINT32)FXMATH_DECIMAL_RSHIFT32BIT(val); + m_uHi = 0; + m_uFlags = 0; +} +CFX_Decimal::CFX_Decimal(FX_UINT32 val) +{ + m_uLo = (FX_UINT32)val; + m_uMid = m_uHi = 0; + m_uFlags = 0; +} +CFX_Decimal::CFX_Decimal(FX_UINT32 lo, FX_UINT32 mid, FX_UINT32 hi, FX_BOOL neg, FX_UINT8 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(FX_INT32 val) +{ + if(val >= 0) { + *this = CFX_Decimal((FX_UINT32)val); + } else { + *this = CFX_Decimal((FX_UINT32) - val); + SetNegate(); + } +} +CFX_Decimal::CFX_Decimal(FX_INT64 val) +{ + if(val >= 0) { + *this = CFX_Decimal((FX_UINT64)val); + } else { + *this = CFX_Decimal((FX_UINT64) - val); + SetNegate(); + } +} +CFX_Decimal::CFX_Decimal(FX_FLOAT val, FX_UINT8 scale ) +{ + FX_FLOAT newval = fabs(val); + FX_UINT64 phi, pmid, plo; + plo = (FX_UINT64)newval; + pmid = (FX_UINT64)(newval / 1e32); + phi = (FX_UINT64)(newval / 1e64); + newval = FXSYS_fmod(newval, 1.0f); + for(FX_UINT8 iter = 0; iter < scale; iter++) { + fxmath_decimal_helper_mul10(phi, pmid, plo); + newval *= 10; + plo += (FX_UINT64)newval; + newval = FXSYS_fmod(newval, 1.0f); + } + plo += FXSYS_round(newval); + fxmath_decimal_helper_normalize(phi, pmid, plo); + m_uHi = (FX_UINT32)phi; + m_uMid = (FX_UINT32)pmid; + m_uLo = (FX_UINT32)plo; + m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(val < 0 && IsNotZero(), scale); +} +CFX_Decimal::CFX_Decimal(FX_WSTR strObj) +{ + FX_LPCWSTR str = strObj.GetPtr(); + FX_LPCWSTR strBound = str + strObj.GetLength(); + FX_BOOL pointmet = 0; + FX_BOOL negmet = 0; + FX_UINT8 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((FX_UINT64)m_uMid * 0xA); + m_uMid = m_uMid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((FX_UINT64)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(FX_BSTR strObj) +{ + CFX_WideString wstrObj; + wstrObj.ConvertFrom(strObj); + *this = CFX_Decimal(wstrObj); +} +CFX_Decimal::operator CFX_WideString() const +{ + CFX_WideString retString; + CFX_WideString tmpbuf; + FX_UINT64 phi = m_uHi, pmid = m_uMid, plo = m_uLo; + while(phi || pmid || plo) { + tmpbuf += fxmath_decimal_helper_div10(phi, pmid, plo) + '0'; + } + FX_UINT8 outputlen = (FX_UINT8)tmpbuf.GetLength(); + FX_UINT8 scale = (FX_UINT8)FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); + while (scale >= outputlen) { + tmpbuf += '0'; + outputlen++; + } + if (FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero()) { + retString += '-'; + } + for (FX_UINT8 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); + FX_INT8 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(FX_UINT8 newscale) +{ + FX_UINT8 oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); + if (newscale > oldscale) { + FX_UINT64 phi = m_uHi, pmid = m_uMid, plo = m_uLo; + for (FX_UINT8 iter = 0; iter < newscale - oldscale; iter++) { + fxmath_decimal_helper_mul10(phi, pmid, plo); + } + m_uHi = (FX_UINT32)phi; + m_uMid = (FX_UINT32)pmid; + m_uLo = (FX_UINT32)plo; + m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale); + } else if (newscale < oldscale) { + FX_UINT64 phi, pmid, plo; + phi = 0, pmid = 0, plo = 5; + { + for(FX_UINT8 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(FX_UINT8 iter = 0; iter < oldscale - newscale; iter++) { + fxmath_decimal_helper_div10(phi, pmid, plo); + } + } + m_uHi = (FX_UINT32)phi; + m_uMid = (FX_UINT32)pmid; + m_uLo = (FX_UINT32)plo; + m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale); + } +} +FX_UINT8 CFX_Decimal::GetScale() +{ + FX_UINT8 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) +{ + FX_UINT64 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 = (FX_UINT32)nums[2]; + m_uMid = (FX_UINT32)nums[1]; + m_uLo = (FX_UINT32)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) +{ + FX_UINT32 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; +} +FX_INT8 CFX_Decimal::Compare (const CFX_Decimal& val) const +{ + CFX_Decimal lhs = *this, rhs = val; + FX_INT8 retVal = 0; + if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) { + FX_UINT8 scale = FX_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)) { + FX_UINT8 scale = FX_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) { + FX_UINT64 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 = (FX_UINT32)phi; + lhs.m_uMid = (FX_UINT32)pmid; + lhs.m_uLo = (FX_UINT32)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 +{ + FX_UINT64 a[3] = {m_uLo, m_uMid, m_uHi}, b[3] = {val.m_uLo, val.m_uMid, val.m_uHi}; + FX_UINT64 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); + FX_UINT8 scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) + FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags); + fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale); + return CFX_Decimal((FX_UINT32)c[0], (FX_UINT32)c[1], (FX_UINT32)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); + FX_UINT64 a[7] = {m_uLo, m_uMid, m_uHi}, b[3] = {val.m_uLo, val.m_uMid, val.m_uHi}, c[7] = {0}; + FX_UINT8 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); + } + FX_UINT8 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((FX_UINT32)c[0], (FX_UINT32)c[1], (FX_UINT32)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 new file mode 100644 index 0000000000..7698388020 --- /dev/null +++ b/xfa/src/fgas/src/localization/fx_localeimp.h @@ -0,0 +1,74 @@ +// 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_Object +{ +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(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const; + virtual void GetDayName(FX_INT32 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_Object +{ +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, FX_WSTR wsCategory, CFX_WideString& wsPurgePattern); + IFX_Locale* GetNumericFormat(const CFX_WideString& wsPattern, FX_INT32& iDotIndex, FX_DWORD& dwStyle, CFX_WideString& wsPurgePattern); + FX_BOOL FormatStrNum(FX_WSTR 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(FX_WSTR 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 new file mode 100644 index 0000000000..3b93f101a3 --- /dev/null +++ b/xfa/src/fgas/src/localization/fx_localemgr.cpp @@ -0,0 +1,100 @@ +// 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 "../fgas_base.h" +#include "fx_localemgr.h" +IFX_LocaleMgr* FX_LocaleMgr_Create(FX_LPCWSTR pszLocalPath, FX_WORD wDefaultLCID) +{ + void* pPathHandle = FX_OpenFolder(pszLocalPath); + if (!pPathHandle) { + return NULL; + } + CFX_LocaleMgr* pLocaleMgr = FX_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((FX_LPVOID)(FX_UINTPTR)dwLCID)) { + delete pXmlLocale; + } else { + pLocaleMgr->m_lcid2xml.SetAt((FX_LPVOID)(FX_UINTPTR)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) { + FX_LPVOID plcid; + IFX_Locale* pLocale = NULL; + m_lcid2locale.GetNextAssoc(ps, plcid, (void*&)pLocale); + pLocale->Release(); + } + m_lcid2locale.RemoveAll(); + ps = m_lcid2xml.GetStartPosition(); + while (ps) { + FX_LPVOID 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((FX_LPVOID)(FX_UINTPTR)lcid); + if (!pLocale) { + CXML_Element* pxml = (CXML_Element*)m_lcid2xml.GetValueAt((FX_LPVOID)(FX_UINTPTR)lcid); + if (pxml) { + pLocale = IFX_Locale::Create(pxml); + m_lcid2locale.SetAt((FX_LPVOID)(FX_UINTPTR)lcid, pLocale); + } + } + return pLocale; +} +IFX_Locale* CFX_LocaleMgr::GetLocaleByName(FX_WSTR wsLocaleName) +{ + return NULL; +} diff --git a/xfa/src/fgas/src/localization/fx_localemgr.h b/xfa/src/fgas/src/localization/fx_localemgr.h new file mode 100644 index 0000000000..b23940e8d5 --- /dev/null +++ b/xfa/src/fgas/src/localization/fx_localemgr.h @@ -0,0 +1,27 @@ +// 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_Object +{ +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(FX_WSTR 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 new file mode 100644 index 0000000000..b41ee3fef4 --- /dev/null +++ b/xfa/src/fgas/src/xml/fx_sax_imp.cpp @@ -0,0 +1,720 @@ +// 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 "../fgas_base.h" +#include "fx_sax_imp.h" +IFX_SAXReader* FX_SAXReader_Create() +{ + return FX_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 = FX_MIN(dwLen, FX_SAXFILE_BUFSIZE); + m_pBuf = FX_Alloc(FX_BYTE, m_dwBufSize); + if (!m_pBuf) { + return FALSE; + } + 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 = FX_MIN(dwSize, FX_SAXFILE_BUFSIZE); + 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; +} +#define FX_SAXCHARTYPE_Normal 0 +#define FX_SAXCHARTYPE_Space 1 +static FX_BYTE g_SAX_CharType[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +CFX_SAXReader::CFX_SAXReader() + : m_File() + , m_pHandler(NULL) + , m_iState(-1) + , m_pRoot(NULL) + , m_pCurItem(NULL) + , m_dwItemID(0) + , m_iDataSize(256) + , m_iNameSize(256) + , m_pCommentContext(NULL) + , m_dwParseMode(0) +{ + m_pszData = (FX_LPBYTE)FX_Alloc(FX_BYTE, m_iDataSize); + m_pszName = (FX_LPBYTE)FX_Alloc(FX_BYTE, 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 = FX_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(FX_BYTE ch) +{ + ReallocDataBuffer(); + m_pszData[m_iDataPos++] = ch; +} +inline void CFX_SAXReader::AppendName(FX_BYTE 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 = (FX_LPBYTE)FX_Realloc(FX_BYTE, 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 = (FX_LPBYTE)FX_Realloc(FX_BYTE, m_pszName, m_iNameSize); +} +inline FX_BOOL CFX_SAXReader::SkipSpace(FX_BYTE ch) +{ + return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21; +} +FX_INT32 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 = FX_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, +}; +FX_INT32 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; + FX_LPCBYTE 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(FX_BYTE ch) +{ + ReallocDataBuffer(); + m_pszData[m_iDataPos] = ch; + if (m_iEntityStart > -1 && ch == ';') { + FX_INT32 iSaveEntityStart = m_iEntityStart; + CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1, m_iDataPos - m_iEntityStart - 1); + FX_INT32 iLen = csEntity.GetLength(); + if (iLen > 0) { + if (csEntity[0] == '#') { + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) { + ch = 0; + FX_BYTE w; + if (iLen > 1 && csEntity[1] == 'x') { + for (FX_INT32 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 (FX_INT32 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 = FX_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() +{ + FX_INT32 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(FX_BYTE)) == 0 + && FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]", 2 * sizeof(FX_BYTE)) == 0) { + Pop(); + m_iDataLength -= 9; + m_dwDataOffset += 7; + FXSYS_memmove(m_pszData , m_pszData + 7, m_iDataLength * sizeof(FX_BYTE)); + 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 new file mode 100644 index 0000000000..f18173183f --- /dev/null +++ b/xfa/src/fgas/src/xml/fx_sax_imp.h @@ -0,0 +1,140 @@ +// 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_ +#define FX_SAXFILE_BUFSIZE 32768 +class CFX_SAXFile : public CFX_Object +{ +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; + FX_LPBYTE 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_Object +{ +public: + CFX_SAXItem() : m_pNode(NULL) + , m_eNode(FX_SAXNODE_Unknown) + , m_dwID(0) + , m_bSkip(FALSE) + , m_pPrev(NULL) + , m_pNext(NULL) + {} + FX_LPVOID 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_Object +{ +public: + CFX_SAXCommentContext() : m_iHeaderCount(0) + , m_iTailCount(0) + { + } + FX_INT32 m_iHeaderCount; + FX_INT32 m_iTailCount; +}; +class CFX_SAXReader : public IFX_SAXReader, public CFX_Object +{ +public: + CFX_SAXReader(); + ~CFX_SAXReader(); + virtual void Release() + { + delete this; + } + virtual FX_INT32 StartParse(IFX_FileRead *pFile, FX_DWORD dwStart = 0, FX_DWORD dwLen = -1, FX_DWORD dwParseMode = 0); + virtual FX_INT32 ContinueParse(IFX_Pause *pPause = NULL); + virtual void SkipCurrentNode(); + virtual void SetHandler(IFX_SAXReaderHandler *pHandler); + void AppendData(FX_BYTE ch); + void AppendName(FX_BYTE 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; + FX_INT32 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; + FX_BYTE m_CurByte; + FX_DWORD m_dwDataOffset; + CFX_ByteArray m_SkipStack; + FX_BYTE m_SkipChar; + FX_DWORD m_dwNodePos; + FX_LPBYTE m_pszData; + FX_INT32 m_iDataSize; + FX_INT32 m_iDataLength; + FX_INT32 m_iEntityStart; + FX_INT32 m_iDataPos; + FX_LPBYTE m_pszName; + FX_INT32 m_iNameSize; + FX_INT32 m_iNameLength; + FX_DWORD m_dwParseMode; + CFX_SAXCommentContext *m_pCommentContext; + void Reset(); + void Push(); + void Pop(); + FX_BOOL SkipSpace(FX_BYTE ch); + void SkipNode(); + void NotifyData(); + void NotifyEnter(); + void NotifyAttribute(); + void NotifyBreak(); + void NotifyClose(); + void NotifyEnd(); + void NotifyTargetData(); + void ReallocDataBuffer(); + void ReallocNameBuffer(); + void ParseChar(FX_BYTE ch); +}; +#endif -- cgit v1.2.3