?? rtfdecoder.cpp
字號:
/********************************************************************************************/ /* Modification History *//* By Whom When For What *//********************************************************************************************/#include "stdafx.h"#include "RtfDecoder.h"
int Charset2Cpg[256];
// Property descriptions
PROP rgprop [ipropMax] = {
actnByte, propChp, offsetof(CHP, fBold), // ipropBold
actnByte, propChp, offsetof(CHP, fItalic), // ipropItalic
actnByte, propChp, offsetof(CHP, fUnderline), // ipropUnderline
actnWord, propPap, offsetof(PAP, xaLeft), // ipropLeftInd
actnWord, propPap, offsetof(PAP, xaRight), // ipropRightInd
actnWord, propPap, offsetof(PAP, xaFirst), // ipropFirstInd
actnWord, propSep, offsetof(SEP, cCols), // ipropCols
actnWord, propSep, offsetof(SEP, xaPgn), // ipropPgnX
actnWord, propSep, offsetof(SEP, yaPgn), // ipropPgnY
actnWord, propDop, offsetof(DOP, xaPage), // ipropXaPage
actnWord, propDop, offsetof(DOP, yaPage), // ipropYaPage
actnWord, propDop, offsetof(DOP, xaLeft), // ipropXaLeft
actnWord, propDop, offsetof(DOP, xaRight), // ipropXaRight
actnWord, propDop, offsetof(DOP, yaTop), // ipropYaTop
actnWord, propDop, offsetof(DOP, yaBottom), // ipropYaBottom
actnWord, propDop, offsetof(DOP, pgnStart), // ipropPgnStart
actnByte, propSep, offsetof(SEP, sbk), // ipropSbk
actnByte, propSep, offsetof(SEP, pgnFormat), // ipropPgnFormat
actnByte, propDop, offsetof(DOP, fFacingp), // ipropFacingp
actnByte, propDop, offsetof(DOP, fLandscape), // ipropLandscape
actnByte, propPap, offsetof(PAP, just), // ipropJust
actnSpec, propPap, 0, // ipropPard
actnSpec, propChp, 0, // ipropPlain
actnSpec, propSep, 0, // ipropSectd
};
// Keyword descriptions
SYM rgsymRtf[] = {
// keyword dflt fPassDflt kwd idx
"b", 1, fFalse, kwdProp, ipropBold,
"u", 1, fFalse, kwdProp, ipropUnderline,
"i", 1, fFalse, kwdProp, ipropItalic,
"li", 0, fFalse, kwdProp, ipropLeftInd,
"ri", 0, fFalse, kwdProp, ipropRightInd,
"fi", 0, fFalse, kwdProp, ipropFirstInd,
"cols", 1, fFalse, kwdProp, ipropCols,
"sbknone", sbkNon, fTrue, kwdProp, ipropSbk,
"sbkcol", sbkCol, fTrue, kwdProp, ipropSbk,
"sbkeven", sbkEvn, fTrue, kwdProp, ipropSbk,
"sbkodd", sbkOdd, fTrue, kwdProp, ipropSbk,
"sbkpage", sbkPg, fTrue, kwdProp, ipropSbk,
"pgnx", 0, fFalse, kwdProp, ipropPgnX,
"pgny", 0, fFalse, kwdProp, ipropPgnY,
"pgndec", pgDec, fTrue, kwdProp, ipropPgnFormat,
"pgnucrm", pgURom, fTrue, kwdProp, ipropPgnFormat,
"pgnlcrm", pgLRom, fTrue, kwdProp, ipropPgnFormat,
"pgnucltr", pgULtr, fTrue, kwdProp, ipropPgnFormat,
"pgnlcltr", pgLLtr, fTrue, kwdProp, ipropPgnFormat,
"qc", justC, fTrue, kwdProp, ipropJust,
"ql", justL, fTrue, kwdProp, ipropJust,
"qr", justR, fTrue, kwdProp, ipropJust,
"qj", justF, fTrue, kwdProp, ipropJust,
"paperw", 12240, fFalse, kwdProp, ipropXaPage,
"paperh", 15480, fFalse, kwdProp, ipropYaPage,
"margl", 1800, fFalse, kwdProp, ipropXaLeft,
"margr", 1800, fFalse, kwdProp, ipropXaRight,
"margt", 1440, fFalse, kwdProp, ipropYaTop,
"margb", 1440, fFalse, kwdProp, ipropYaBottom,
"pgnstart", 1, fTrue, kwdProp, ipropPgnStart,
"facingp", 1, fTrue, kwdProp, ipropFacingp,
"landscape",1, fTrue, kwdProp, ipropLandscape,
"par", 0, fFalse, kwdChar, 0x0a,
"\0x0a", 0, fFalse, kwdChar, 0x0a,
"\0x0d", 0, fFalse, kwdChar, 0x0a,
"tab", 0, fFalse, kwdChar, 0x09,
"ldblquote",0, fFalse, kwdChar, '"',
"rdblquote",0, fFalse, kwdChar, '"',
"bin", 0, fFalse, kwdSpec, ipfnBin,
"*", 0, fFalse, kwdSpec, ipfnSkipDest,
"'", 0, fFalse, kwdSpec, ipfnHex,
"author", 0, fFalse, kwdDest, idestSkip,
"buptim", 0, fFalse, kwdDest, idestSkip,
"colortbl", 0, fFalse, kwdDest, idestSkip,
"comment", 0, fFalse, kwdDest, idestSkip,
"creatim", 0, fFalse, kwdDest, idestSkip,
"doccomm", 0, fFalse, kwdDest, idestSkip,
//cjg add
"fcharset", 0, fFalse, kwdSpec, idestSkip,
"fonttbl", 0, fFalse, kwdDest, idestSkip,
"footer", 0, fFalse, kwdDest, idestSkip,
"footerf", 0, fFalse, kwdDest, idestSkip,
"footerl", 0, fFalse, kwdDest, idestSkip,
"footerr", 0, fFalse, kwdDest, idestSkip,
"footnote", 0, fFalse, kwdDest, idestSkip,
"ftncn", 0, fFalse, kwdDest, idestSkip,
"ftnsep", 0, fFalse, kwdDest, idestSkip,
"ftnsepc", 0, fFalse, kwdDest, idestSkip,
"header", 0, fFalse, kwdDest, idestSkip,
"headerf", 0, fFalse, kwdDest, idestSkip,
"headerl", 0, fFalse, kwdDest, idestSkip,
"headerr", 0, fFalse, kwdDest, idestSkip,
"info", 0, fFalse, kwdDest, idestSkip,
"keywords", 0, fFalse, kwdDest, idestSkip,
"operator", 0, fFalse, kwdDest, idestSkip,
"pict", 0, fFalse, kwdDest, idestSkip,
"printim", 0, fFalse, kwdDest, idestSkip,
"private1", 0, fFalse, kwdDest, idestSkip,
"revtim", 0, fFalse, kwdDest, idestSkip,
"rxe", 0, fFalse, kwdDest, idestSkip,
"stylesheet", 0, fFalse, kwdDest, idestSkip,
"subject", 0, fFalse, kwdDest, idestSkip,
"tc", 0, fFalse, kwdDest, idestSkip,
"title", 0, fFalse, kwdDest, idestSkip,
"txe", 0, fFalse, kwdDest, idestSkip,
"xe", 0, fFalse, kwdDest, idestSkip,
"{", 0, fFalse, kwdChar, '{',
"}", 0, fFalse, kwdChar, '}',
"\\", 0, fFalse, kwdChar, '\\'
};
class NULL_CLASS
{
public:
NULL_CLASS()
{
memset(Charset2Cpg,-1,sizeof(Charset2Cpg));
Charset2Cpg[0]=1252; //ANSI_CHARSET
Charset2Cpg[2]=936; //ANSI_CHARSET
Charset2Cpg[128]=932; //SHIFTJIS_CHARSET
Charset2Cpg[129]=949; //HANGUL_CHARSET
Charset2Cpg[134]=936; //GB2312_CHARSET
Charset2Cpg[136]=950; //CHINESEBIG5_CHARSET
Charset2Cpg[161]=1253; //GREEK_CHARSET
Charset2Cpg[162]=1254; //TURKISH_CHARSET
Charset2Cpg[177]=1255; //HEBREW_CHARSET
Charset2Cpg[178]=1256; //ARABIC_CHARSET
Charset2Cpg[186]=1257; //BALTIC_CHARSET
Charset2Cpg[204]=1251; //RUSSIAN_CHARSET
Charset2Cpg[222]=874; //THAI_CHARSET
Charset2Cpg[238]=1250; //EE_CHARSET
Charset2Cpg[255]=1252; //OEM_CHARSET
}
~NULL_CLASS()
{}
}aa;
CRtfDecoder::CRtfDecoder(CPublicResource *ps):
CDecoderBase(ps)
{
coderName="RTF";
version=0x0100;
m_cGroup=0;
m_cbBin=0;
m_fSkipDestIfUnk=fFalse;
m_lParam=0;
m_previousparam=-1;
m_midbuflen=0;
m_outbuflen=0;
m_curCharset=0;
m_curCodePage=-1;
m_previousCodeP=-1;
m_firstentry=true;
rds=rdsNorm;
ris=risNorm;
memset(&chp,0,sizeof(CHP));
memset(&pap,0,sizeof(PAP));
memset(&sep,0,sizeof(SEP));
memset(&dop,0,sizeof(DOP));
psave=NULL;
isymMax = sizeof(rgsymRtf) / sizeof(SYM);
p_midbuf=new unsigned char[MIDBUFSIZE];
p_outbuf=new unsigned char[OUTBUFSIZE];
memset(p_midbuf,0,MIDBUFSIZE);
memset(p_outbuf,0,OUTBUFSIZE);
memset(allCharset,0,sizeof(allCharset));
}
CRtfDecoder::~CRtfDecoder()
{
if(p_midbuf)delete p_midbuf;
p_midbuf=NULL;
if(p_outbuf)delete p_outbuf;
p_outbuf=NULL;
}
// ecApplyPropChange
// Set the property identified by _iprop_ to the value _val_.
int CRtfDecoder::ecApplyPropChange(IPROP iprop, int val)
{
char *pb;
if (rds == rdsSkip) // If we're skipping text,
return ecOK; // don't do anything.
switch (rgprop[iprop].prop)
{
case propDop:
pb = (char *)&dop;
break;
case propSep:
pb = (char *)&sep;
break;
case propPap:
pb = (char *)&pap;
break;
case propChp:
pb = (char *)&chp;
break;
default:
if (rgprop[iprop].actn != actnSpec)
return ecBadTable;
break;
}
switch (rgprop[iprop].actn)
{
case actnByte:
pb[rgprop[iprop].offset] = (unsigned char) val;
break;
case actnWord:
(*(int *) (pb+rgprop[iprop].offset)) = val;
break;
case actnSpec:
return ecParseSpecialProperty(iprop, val);
break;
default:
return ecBadTable;
}
return ecOK;
}
// ecParseSpecialProperty
// Set a property that requires code to evaluate.
int CRtfDecoder::ecParseSpecialProperty(IPROP iprop, int val)
{
switch (iprop)
{
case ipropPard:
memset(&pap, 0, sizeof(pap));
return ecOK;
case ipropPlain:
memset(&chp, 0, sizeof(chp));
return ecOK;
case ipropSectd:
memset(&sep, 0, sizeof(sep));
return ecOK;
default:
return ecBadTable;
}
return ecBadTable;
}
// ecTranslateKeyword.
// Search rgsymRtf for szKeyword and evaluate it appropriately.
// Inputs:
// szKeyword: The RTF control to evaluate.
// param: The parameter of the RTF control.
// fParam: fTrue if the control had a parameter; (that is, if param is valid)
// fFalse if it did not.
int CRtfDecoder::ecTranslateKeyword(char *szKeyword, int param, bool fParam)
{
int isym;
if(fParam)
{
if(!strcmp(szKeyword,"f"))
{
if(param>m_previousparam)
{
m_previousparam=param;
}
else
{
m_curCharset=allCharset[param];
m_curCodePage=Charset2Cpg[m_curCharset];
ecMidBuftoOutBuf();
m_previousCodeP=m_curCodePage;
}
}
if(!strcmp(szKeyword,"fcharset"))
{
allCharset[m_previousparam]=param;
}
}
// search for szKeyword in rgsymRtf
for (isym = 0; isym < isymMax; isym++)
if (strcmp(szKeyword, rgsymRtf[isym].szKeyword) == 0)
break;
if (isym == isymMax) // control word not found
{
if (m_fSkipDestIfUnk) // if this is a new destination
rds = rdsSkip; // skip the destination
// else just discard it
m_fSkipDestIfUnk = fFalse;
return ecOK;
}
// found it! use kwd and idx to determine what to do with it.
m_fSkipDestIfUnk = fFalse;
switch (rgsymRtf[isym].kwd)
{
case kwdProp:
if (rgsymRtf[isym].fPassDflt || !fParam)
param = rgsymRtf[isym].dflt;
return ecApplyPropChange((IPROP)rgsymRtf[isym].idx, param);
case kwdChar:
return ecParseChar(rgsymRtf[isym].idx);
case kwdDest:
return ecChangeDest((IDEST)rgsymRtf[isym].idx);
case kwdSpec:
return ecParseSpecialKeyword((IPFN)rgsymRtf[isym].idx);
default:
return ecBadTable;
}
return ecBadTable;
}
// ecChangeDest
// Change to the destination specified by idest.
// There's usually more to do here than this...
int CRtfDecoder::ecChangeDest(IDEST idest)
{
if (rds == rdsSkip) // if we're skipping text,
return ecOK; // don't do anything
rds = rdsSkip ;
/*switch (idest)
{
default:
rds = rdsSkip; // when in doubt, skip it...
break;
}*/
return ecOK;
}
//ecEndGroupAction
// The destination specified by rds is coming to a close.
// If there's any cleanup that needs to be done, do it now.
int CRtfDecoder::ecEndGroupAction(RDS rds)
{
return ecOK;
}
// ecParseSpecialKeyword
// Evaluate an RTF control that needs special processing.
int CRtfDecoder::ecParseSpecialKeyword(IPFN ipfn)
{
if (rds == rdsSkip && ipfn != ipfnBin) // if we're skipping, and it's not
return ecOK; // the \bin keyword, ignore it.
switch (ipfn)
{
case ipfnBin:
ris = risBin;
m_cbBin = m_lParam;
break;
case ipfnSkipDest:
m_fSkipDestIfUnk = fTrue;
break;
case ipfnHex:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -