📄 chnconv_dll.cpp
字号:
#define RTF_HIDDEN 2
#define RTF_FIELD 0x10
#define RTF_FIELD_INST 0x20
#define RTF_FIELD_RESULT 0x40
#define RTF_SHAPE 0x100
#define RTF_SHAPE_RESULT 0x200
#define RTF_FONT_ALT 0x1000
#define RTF_LANG 0x2000
// for nIncreaseDepth
#define INCDEPTH_JIANTI 1
#define INCDEPTH_FANTI 2
#define INCDEPTH_PINYIN 3
#define INCDEPTH_NIHAO_PINYIN 4
typedef struct {
DEPTH_INFO *pTable ;
int nTableSize ; // number of items
int nDepth ;
} DEPTH_INFO_TABLE ;
DEPTH_INFO *GetDepthInfo ( DEPTH_INFO_TABLE *pDepthInfoTable, int nIncrease ) ;
typedef struct {
int *pTable ; // RTF 偺僼僅儞僩斣崋偵懳墳乮奿擺偝傟傞壙偼奺僼僅儞僩偺僐乕僪儁乕僕乯
int nTableSize ; // number of items
} FONT_TABLE_INFO ;
int GetFontTableValue ( FONT_TABLE_INFO *pFontTableInfo, int nFont, int nDefaultCodePage ) ;
int SetFontTableValue ( FONT_TABLE_INFO *pFontTableInfo, int nFont, int nCodePage ) ;
// 儕僢僠僥僉僗僩傪僥僉僗僩僼傽僀儖傪曄姺偡傞
// 惉岟偟偨偲偒偼 0 傪曉偡
// 幐攕偟偨偲偒偼 1 埲忋偺巜掕偝傟偨掕悢傪曉偡
int ChnconvRtf ( CHNCONVDATA *pData ) {
char szTag [ MAX_PATH ] ;
int IsRtfFormat = 0 ; // 0: 枹専嵏, 1: 専嵏嵪傒
DEPTH_INFO_TABLE DepthInfoTable = { 0 } ;
FONT_TABLE_INFO FontTableInfo = { 0 } ;
STOREDCHARSA *FontName = NULL ;
STOREDCHARSA *AltFontName = NULL ;
int nCurrentCodePage = CP_ANSI_EUROPEAN ; // 僼僅儞僩偺僐乕僪儁乕僕
int nFontMax = 0 ;
int nDstFont = -1 ;
int nDstGothicFont = -1 ;
const char *szDstFont ;
const char *szDstGothicFont ;
int nDstLang ;
int nDstLangFe ;
int nDstLangFeNp ;
int nKgFont = -1 ; // CW擖弌椡帪偺傒巊梡
int nKgGothicFont = -1 ;
int nCwnfFont = -1 ; // CWN擖弌椡帪偺傒巊梡
int nCwnfGothicFont = -1 ;
int nNh3pFont = -1 ; // NH弌椡帪偺傒巊梡
int nPinyinFont = -1 ; // GB僺儞僀儞梡暥帤偺僼僅儞僩
int nPinyinGothicFont = -1 ;
int IsExistSrcFont = 0 ; // nSrcCodePage 偺僼僅儞僩偑懚嵼偡傞偐丠
int C ; // 暥帤
int cLeadChar = 0 ; // 傕偟巜掕偝傟偰偄偨傜丄師偺 C 偼俀僶僀僩栚
int IsCodeDirect = 0 ; // 暥帤傪悢帤偱側偔丄偦偺傑傑捈愙丠
int IsCharacterHexa = 0 ; // ASCII暥帤傪悢帤偱弌椡
int cUnicode = 0 ; // Unicode偱弌椡
int cUnicodeLead = 0 ; // Unicode 係僶僀僩偺愭摢俀僶僀僩
int nCountChar = 0 ;
#if FIELD_DETECT
STOREDCHARSA *Field = NULL ;
int IsFieldInstHidden = 0 ;
#endif
// 暥帤曄姺娭悢傪弶婜壔
CONVERTCHARACTER *ConvertChineseCharacter = GetConvertFunction ( pData->nSrcCodePage, pData->nDstCodePage, 0 ) ;
if ( ! ConvertChineseCharacter ) return CONV_ERROR_CODEPAGE ;
// 暥帤曄姺娭悢傪弶婜壔乮斏懱帤梡乯
CONVERTCHARACTER *ConvertChineseCharacterFanti = GetConvertFunction ( pData->nSrcCodePage, pData->nDstCodePage, pData->dwConversionMode & CONVMODE_SENSE_CW_FANTIZI ) ;
if ( ! ConvertChineseCharacterFanti ) ConvertChineseCharacterFanti = ConvertChineseCharacter ;
// 暥帤曄姺娭悢傪弶婜壔乮CW乯
CONVERTCHARACTER *ConvertChineseCharacterToCw = GetConvertFunction ( pData->nSrcCodePage, CP_JAPANESE_CW, 0 ) ;
// 僼僅儞僩柤傪弶婜壔
InitRtfFontName ( & szDstFont, & szDstGothicFont, pData ) ;
// 弌椡尵岅忣曬傪弶婜壔
nDstLang = MAKELANGID ( LANG_ENGLISH, SUBLANG_ENGLISH_US ) ;
switch ( pData->nDstCodePage & CP_DEFINE_CODEPAGE ) {
case CP_CHINESE_SIMPLIFIED : nDstLangFe = nDstLangFeNp = MAKELANGID ( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED ) ; break ;
case CP_CHINESE_TRADITIONAL : nDstLangFe = nDstLangFeNp = MAKELANGID ( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ) ; break ;
case CP_JAPANESE : nDstLangFe = nDstLangFeNp = MAKELANGID ( LANG_JAPANESE, SUBLANG_DEFAULT ) ; break ;
default : nDstLangFe = nDstLangFeNp = MAKELANGID ( LANG_ENGLISH, SUBLANG_ENGLISH_US ) ; break ;
}
// 怺偝忣曬僥乕僽儖傪弶婜壔
DEPTH_INFO *pDepthInfo = GetDepthInfo ( & DepthInfoTable, 0 ) ;
if ( ! pDepthInfo ) { pData->nError = CONV_ERROR_MEMORY ; goto CAUGHT_ERROR ; }
pDepthInfo->nFont = -1 ;
pDepthInfo->nAltFont = -1 ;
pDepthInfo->nCharset = DEFAULT_CHARSET ;
pDepthInfo->nDefaultCodePage = CP_ANSI_EUROPEAN ;
while ( ( C = StreamRead ( pData->StreamIn ) ) != EOF ) {
// 儊僢僙乕僕張棟
if ( ! ( nCountChar & PEEK_MESSAGE_CONUT_MASK ) ) {
if ( pData->dwConversionMode & CONVMODE_PEEKMESSAGE ) PeekMessageProc ( pData ) ;
if ( pData->nError ) goto CAUGHT_ERROR ;
if ( StreamError ( pData->StreamIn ) ) { pData->nError = CONV_ERROR_READ ; goto CAUGHT_ERROR ; }
if ( StreamError ( pData->StreamOut ) ) { pData->nError = CONV_ERROR_WRITE ; goto CAUGHT_ERROR ; }
}
nCountChar ++ ;
// 嫮惂廔椆
if ( IsAborted ) { pData->nError = CONV_ERROR_ABORTED ; goto CAUGHT_ERROR ; }
// 怺偝偺愝掕
if ( ! IsCodeDirect || ! cLeadChar ) {
if ( C == BRACE_END ) {
if ( pDepthInfo->nIncreaseDepth ) {
StreamWrite ( BRACE_END, pData->StreamOut ) ;
pDepthInfo->nIncreaseDepth = 0 ;
}
pDepthInfo = GetDepthInfo ( & DepthInfoTable, -1 ) ;
if ( ! pDepthInfo ) break ;
if ( ! ( pDepthInfo->dwAttributes & RTF_FONT_TABLE ) && ( pDepthInfo + 1 )->dwAttributes & RTF_FONT_TABLE ) {
if ( IsExistSrcFont ) {
// 弌椡僼僅儞僩柤傪彂偒崬傓
if ( nDstFont < 0 ) WriteFontName ( nDstFont = ++ nFontMax, szDstFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 0, pData->StreamOut ) ;
if ( ! mbsicmp_cp ( szDstFont, szDstGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE ) ) nDstGothicFont = nDstFont ;
if ( nDstGothicFont < 0 ) WriteFontName ( nDstGothicFont = ++ nFontMax, szDstGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 1, pData->StreamOut ) ;
// 僺儞僀儞梡弌椡僼僅儞僩柤傪彂偒崬傓
if ( pData->dwConversionMode & CONVMODE_PINYIN_BY_ASCII ) {
if ( nPinyinFont < 0 ) WriteFontName ( nPinyinFont = ++ nFontMax, pData->szPinyinFont, CP_ANSI_EUROPEAN, 0, pData->StreamOut ) ;
if ( ! stricmp ( pData->szPinyinFont, pData->szPinyinGothicFont ) ) nPinyinGothicFont = nPinyinFont ;
if ( nPinyinGothicFont < 0 ) WriteFontName ( nPinyinGothicFont = ++ nFontMax, pData->szPinyinGothicFont, CP_ANSI_EUROPEAN, 1, pData->StreamOut ) ;
}
// 奼挘僼僅儞僩柤傪彂偒崬傓
if ( pData->nDstCodePage == CP_JAPANESE_CW ) {
if ( pData->dwConversionMode & CONVMODE_OUTPUT_NEW_FONT ) {
if ( nKgFont < 0 ) WriteFontName ( nKgFont = ++ nFontMax, szKg7Font, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 0, pData->StreamOut ) ;
if ( ! mbsicmp_cp ( szKg7Font, szKg7GothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE ) ) nKgGothicFont = nKgFont ;
if ( nKgGothicFont < 0 ) WriteFontName ( nKgGothicFont = ++ nFontMax, szKg7GothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 1, pData->StreamOut ) ;
}
else {
if ( nKgFont < 0 ) WriteFontName ( nKgFont = ++ nFontMax, szKgFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 0, pData->StreamOut ) ;
if ( ! mbsicmp_cp ( szKgFont, szKgGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE ) ) nKgGothicFont = nKgFont ;
if ( nKgGothicFont < 0 ) WriteFontName ( nKgGothicFont = ++ nFontMax, szKgGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 1, pData->StreamOut ) ;
}
}
if ( pData->nDstCodePage == CP_JAPANESE_CWN ) {
if ( nCwnfFont < 0 ) WriteFontName ( nCwnfFont = ++ nFontMax, szCwnfFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 0, pData->StreamOut ) ;
if ( ! mbsicmp_cp ( szCwnfFont, szCwnfGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE ) ) nCwnfGothicFont = nCwnfFont ;
if ( nCwnfGothicFont < 0 ) WriteFontName ( nCwnfGothicFont = ++ nFontMax, szCwnfGothicFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 1, pData->StreamOut ) ;
}
if ( pData->nDstCodePage == CP_JAPANESE_NH ) {
if ( nNh3pFont < 0 ) WriteFontName ( nNh3pFont = ++ nFontMax, szNh3pFont, pData->nDstCodePage & CP_DEFINE_CODEPAGE, 0, pData->StreamOut ) ;
}
}
// 捠忢偼巊傢傟側偄
ClearStoredCharsA ( FontName ) ;
ClearStoredCharsA ( AltFontName ) ;
}
StreamWrite ( C, pData->StreamOut ) ;
continue ;
}
if ( C == BRACE_START ) {
if ( pDepthInfo->nIncreaseDepth ) {
StreamWrite ( BRACE_END, pData->StreamOut ) ;
pDepthInfo->nIncreaseDepth = 0 ;
}
pDepthInfo = GetDepthInfo ( & DepthInfoTable, 1 ) ;
if ( ! pDepthInfo ) { pData->nError = CONV_ERROR_MEMORY ; goto CAUGHT_ERROR ; }
StreamWrite ( C, pData->StreamOut ) ;
continue ;
}
}
// 僄僗働乕僾偺張棟
if ( C == ESCAPE ) {
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
// 俀僶僀僩暥帤傪捈愙擖椡偟偨応崌偺俀僶僀僩栚偺夝庍
// 捠忢偼巊傢傟側偄
if ( IsCodeDirect && cLeadChar && ismbbtrail_cp ( ESCAPE, nCurrentCodePage & CP_DEFINE_CODEPAGE ) ) {
StreamUnread ( C, pData->StreamIn ) ;
C = ESCAPE ;
goto PROCEDURE_OUTPUT_CHAR ;
}
// 暥帤偺庢摼乮16恑僐乕僪乯
if ( C == '\'' ) {
int C0, C1 ;
if ( ( C0 = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( ( C1 = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
szTag [ 0 ] = C0 ;
szTag [ 1 ] = C1 ;
szTag [ 2 ] = 0 ;
C = strtoul ( szTag, NULL, 0x10 ) ;
if ( ! cLeadChar && isascii ( C ) ) IsCharacterHexa = 1 ;
IsCodeDirect = 0 ;
goto PROCEDURE_OUTPUT_CHAR ;
}
// 僞僌傪僶僢僼傽偵庢摼
if ( isascii ( C ) && ( ispunct ( C ) || iscntrl ( C ) ) ) {
szTag [ 0 ] = C ;
szTag [ 1 ] = 0 ;
}
else {
StreamUnread ( C, pData->StreamIn ) ;
int nCount = 0 ;
for ( ; nCount < MAX_PATH ; nCount ++ ) {
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( ! isascii ( C ) || ( isspace ( C ) || iscntrl ( C ) || ispunct ( C ) ) && C != '-' ) break ;
szTag [ nCount ] = C ;
}
StreamUnread ( C, pData->StreamIn ) ;
szTag [ nCount ] = 0 ;
}
// 暥帤偺庢摼乮婰崋乯
for ( int nCount = 0 ; nCount < RTF_ESCAPE_LIST_MAX ; nCount ++ ) {
if ( ! strcmp ( szTag, ( RtfEscapeList [ nCount ] ).szName ) ) {
C = ( RtfEscapeList [ nCount ] ).nCode ;
goto PROCEDURE_OUTPUT_CHAR ;
}
}
// 僼僅儞僩斣崋偺庢摼
if ( szTag [ 0 ] == 'f' && isdigit ( szTag [ 1 ] ) ) {
pDepthInfo->nFont = atoi ( szTag + 1 ) ;
// 僼僅儞僩斣崋偺曄峏
if ( ! ( pDepthInfo->dwAttributes & ( RTF_FONT_TABLE | RTF_HIDDEN ) ) ) {
int nCodePage = GetFontTableValue ( & FontTableInfo, pDepthInfo->nFont, pDepthInfo->nDefaultCodePage ) ;
if ( ( nCodePage & ( CP_DEFINE_CODEPAGE | CP_DEFINE_PSEUDOCODE ) ) == pData->nSrcCodePage ) {
int IsToBeBold ;
int nNewFont = GetNewFontNumber ( pData, nCodePage, nDstFont, nDstGothicFont, nKgFont, nKgGothicFont, nCwnfFont, nCwnfGothicFont, & IsToBeBold ) ;
sprintf ( szTag, "f%u%s", nNewFont, IsToBeBold ? "\\b" : "" ) ;
pDepthInfo->dwAttributes |= RTF_LANG ;
}
}
// 捠忢偼巊傢傟側偄
if ( pDepthInfo->dwAttributes & RTF_FONT_TABLE ) ClearStoredCharsA ( FontName ) ;
goto PROCEDURE_OUTPUT_TAG ;
}
// 戙懼僼僅儞僩斣崋偺庢摼
if ( szTag [ 0 ] == 'a' && szTag [ 1 ] == 'f' && isdigit ( szTag [ 2 ] ) ) {
pDepthInfo->nAltFont = atoi ( szTag + 2 ) ;
// 戙懼僼僅儞僩斣崋偺曄峏
if ( ! ( pDepthInfo->dwAttributes & ( RTF_FONT_TABLE | RTF_HIDDEN ) ) ) {
int nCodePage = GetFontTableValue ( & FontTableInfo, pDepthInfo->nAltFont, pDepthInfo->nDefaultCodePage ) ;
if ( ( nCodePage & ( CP_DEFINE_CODEPAGE | CP_DEFINE_PSEUDOCODE ) ) == pData->nSrcCodePage ) {
int nNewFont = GetNewFontNumber ( pData, nCodePage, nDstFont, nDstGothicFont, nKgFont, nKgGothicFont, nCwnfFont, nCwnfGothicFont, NULL ) ;
sprintf ( szTag, "af%u", nNewFont ) ;
}
}
// 捠忢偼巊傢傟側偄
if ( pDepthInfo->dwAttributes & RTF_FONT_TABLE ) ClearStoredCharsA ( AltFontName ) ;
goto PROCEDURE_OUTPUT_TAG ;
}
// 梋寁側尵岅忣曬傪嶍彍
// 僞僌傪嶍彍偡傞偲偒偼昁偢屻傠偺僗儁乕僗堦偮傕嶍彍偡傞偙偲
if ( ! ( pDepthInfo->dwAttributes & ( RTF_FONT_TABLE | RTF_HIDDEN ) ) ) {
if ( ! strheadcmp ( szTag, szLangTag ) && isdigit ( *( szTag + strlen ( szLangTag ) ) ) ) {
pDepthInfo->nLang = atoi ( szTag + strlen ( szLangTag ) ) ;
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( C != 0x20 ) StreamUnread ( C, pData->StreamIn ) ;
pDepthInfo->dwAttributes |= RTF_LANG ;
continue ;
}
if ( ! strheadcmp ( szTag, szLangFeTag ) && isdigit ( *( szTag + strlen ( szLangFeTag ) ) ) ) {
pDepthInfo->nLangFe = atoi ( szTag + strlen ( szLangFeTag ) ) ;
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( C != 0x20 ) StreamUnread ( C, pData->StreamIn ) ;
pDepthInfo->dwAttributes |= RTF_LANG ;
continue ;
}
if ( ! strheadcmp ( szTag, szLangFeNpTag ) && isdigit ( *( szTag + strlen ( szLangFeNpTag ) ) ) ) {
pDepthInfo->nLangFeNp = atoi ( szTag + strlen ( szLangFeNpTag ) ) ;
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( C != 0x20 ) StreamUnread ( C, pData->StreamIn ) ;
pDepthInfo->dwAttributes |= RTF_LANG ;
continue ;
}
// 暥帤偺庢摼乮Unicode乯
if ( szTag [ 0 ] == 'u' && ( isdigit ( szTag [ 1 ] ) || szTag [ 1 ] == '-' ) ) {
cUnicode = (wchar_t) strtol ( szTag + 1, NULL, 10 ) ;
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( C != 0x20 ) StreamUnread ( C, pData->StreamIn ) ;
continue ;
}
// Unicode偱僗僉僢僾偡傞暥帤悢偺庢摼
if ( ! strheadcmp ( szTag, szCharToSkipTag ) && isdigit ( *( szTag + strlen ( szCharToSkipTag ) ) ) ) {
if ( ( C = StreamRead ( pData->StreamIn ) ) == EOF ) break ;
if ( C != 0x20 ) StreamUnread ( C, pData->StreamIn ) ;
continue ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -