📄 rtfwrit.cpp
字号:
}
//======================== CRTFConverter Base Class ==================================
/*
* CRTFConverter::CRTFConverter()
*
* @mfunc
* RTF Converter constructor
*/
CRTFConverter::CRTFConverter(
CTxtRange * prg, // @parm CTxtRange for transfer
EDITSTREAM * pes, // @parm Edit stream for transfer
DWORD dwFlags, // @parm Converter flags
BOOL fRead) // @parm Initialization for a reader or writer
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFConverter::CRTFConverter");
AssertSz(prg && pes && pes->pfnCallback,
"CRTFWrite::CRTFWrite: Bad RichEdit");
_prg = prg;
_pes = pes;
_ped = prg->GetPed();
_dwFlags = dwFlags;
_ecParseError = ecNoError;
if(!_ctfi)
{
ReadFontSubInfo();
}
#if defined(DEBUG) && !defined(MACPORT)
_hfileCapture = NULL;
#if !defined(PEGASUS)
if(GetProfileIntA("RICHEDIT DEBUG", "RTFCAPTURE", 0))
{
char szTempPath[MAX_PATH] = "\0";
const char cszRTFReadCaptureFile[] = "CaptureRead.rtf";
const char cszRTFWriteCaptureFile[] = "CaptureWrite.rtf";
DWORD cchLength;
SideAssert(cchLength = GetTempPathA(MAX_PATH, szTempPath));
// append trailing backslash if neccessary
if(szTempPath[cchLength - 1] != '\\')
{
szTempPath[cchLength] = '\\';
szTempPath[cchLength + 1] = 0;
}
strcat(szTempPath, fRead ? cszRTFReadCaptureFile :
cszRTFWriteCaptureFile);
SideAssert(_hfileCapture = CreateFileA(szTempPath,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL));
}
#endif // !defined(PEGASUS)
#endif // defined(DEBUG) && !defined(MACPORT)
}
//======================== OLESTREAM functions =======================================
DWORD CALLBACK RTFPutToStream (
RTFWRITEOLESTREAM * OLEStream, //@parm OLESTREAM
const void * pvBuffer, //@parm Buffer to write
DWORD cb) //@parm Bytes to write
{
return OLEStream->Writer->WriteData ((BYTE *)pvBuffer, cb);
}
//============================ CRTFWrite Class ==================================
/*
* CRTFWrite::CRTFWrite()
*
* @mfunc
* RTF writer constructor
*/
CRTFWrite::CRTFWrite(
CTxtRange * prg, // @parm CTxtRange to write
EDITSTREAM * pes, // @parm Edit stream to write to
DWORD dwFlags) // @parm Write flags
: CRTFConverter(prg, pes, dwFlags, FALSE)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::CRTFWrite");
ZeroMemory(&_CF, sizeof(CCharFormat)); // Setup "previous" CF with RTF
_CF.cbSize = sizeof(CHARFORMAT2); // defaults. 12 Pt in twips
_CF.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;// Font info is given
_CF.yHeight = 12*20; // by first font in range
// [see end of LookupFont()]
if (NULL == _ped)
{
Assert(_ped);
_CF.lcid = (LCID)0;
}
else
{
_ped->GetDefaultLCID(&_CF.lcid);
}
// init OleStream
RTFWriteOLEStream.Writer = this;
RTFWriteOLEStream.lpstbl->Put = (DWORD (CALLBACK* )(LPOLESTREAM, const void FAR*, DWORD))
RTFPutToStream;
RTFWriteOLEStream.lpstbl->Get = NULL;
_fIncludeObjects = TRUE;
if (dwFlags == SF_RTFNOOBJS)
_fIncludeObjects = FALSE;
_fNeedDelimeter = FALSE;
_nHeadingStyle = 0; // No headings found
_nNumber = 0; // No paragraph numbering yet
_fCheckInTable = FALSE;
_pPF = NULL;
_pbAnsiBuffer = NULL;
}
/*
* CRTFWrite::FlushBuffer()
*
* @mfunc
* Flushes output buffer
*
* @rdesc
* BOOL TRUE if successful
*/
BOOL CRTFWrite::FlushBuffer()
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::FlushBuffer");
LONG cchWritten;
if (!_cchBufferOut)
return TRUE;
#ifdef DEBUG_PASTE
if (FromTag(tagRTFAsText))
{
CHAR * pchEnd = &_pchRTFBuffer[_cchBufferOut];
CHAR chT = *pchEnd;
*pchEnd = 0;
TraceString(_pchRTFBuffer);
*pchEnd = chT;
}
#endif
_pes->dwError = _pes->pfnCallback(_pes->dwCookie,
(unsigned char *)_pchRTFBuffer,
_cchBufferOut, &cchWritten);
#if defined(DEBUG) && !defined(MACPORT) && !defined(PEGASUS)
if(_hfileCapture)
{
DWORD cbLeftToWrite = _cchBufferOut;
DWORD cbWritten2 = 0;
BYTE *pbToWrite = (BYTE *)_pchRTFBuffer;
while(WriteFile(_hfileCapture,
pbToWrite,
cbLeftToWrite,
&cbWritten2,
NULL) &&
(pbToWrite += cbWritten2,
(cbLeftToWrite -= cbWritten2)));
}
#endif
if (_pes->dwError)
{
_ecParseError = ecPutCharFailed;
return FALSE;
}
AssertSz(cchWritten == _cchBufferOut,
"CRTFW::FlushBuffer: incomplete write");
_cchOut += _cchBufferOut;
_pchRTFEnd = _pchRTFBuffer; // Reset buffer
_cchBufferOut = 0;
return TRUE;
}
/*
* CRTFWrite::PutChar(ch)
*
* @mfunc
* Put out the character <p ch>
*
* @rdesc
* BOOL TRUE if successful
*/
BOOL CRTFWrite::PutChar(
CHAR ch) // @parm char to be put
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::PutChar");
CheckDelimeter(); // If _fNeedDelimeter, may need to
// PutChar(' ')
// Flush buffer if char won't fit
if (_cchBufferOut + 1 >= cachBufferMost && !FlushBuffer())
return FALSE;
*_pchRTFEnd++ = ch; // Store character in buffer
++_cchBufferOut;
return TRUE;
}
/*
* CRTFWrite::CheckInTable(fPutIntbl)
*
* @mfunc
* If _fCheckInTable or !fPutIntbl, output row header RTF. If fPutIntbl
* and _fCheckInTable, output \intbl as well. Note that fPutIntbl is
* FALSE when a PF is being output, since this control word needs to
* be output after the \pard, but the other row RTF needs to be output
* before the \pard.
*
* @rdesc
* BOOL TRUE if in table and outputted all relevant \trowd stuff
*/
BOOL CRTFWrite::CheckInTable(
BOOL fPutIntbl) //@parm TRUE if \intbl should be output
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::CheckInTable");
_fCheckInTable = FALSE;
if(_pPF->InTable())
{
if(!_fRangeHasEOP)
return TRUE;
LONG cTab = _pPF->cTabCount;
LONG h = _pPF->dxOffset;
LONG i, j = _pPF->dxStartIndent;
LONG k = _pPF->wAlignment;
DWORD Tab, Widths;
if (!PutCtrlWord(CWF_STR, i_trowd) || // Reset table properties
h && !PutCtrlWord(CWF_VAL, i_trgaph, h) ||
j && !PutCtrlWord(CWF_VAL, i_trleft, j) ||
IN_RANGE(PFA_RIGHT, k, PFA_CENTER) &&
!PutCtrlWord(CWF_STR, k == PFA_RIGHT ? i_trqr : i_trqc))
{
return FALSE;
}
PutBorders(TRUE);
for(i = 0; i < cTab; i++)
{
Tab = _pPF->rgxTabs[i];
Widths = Tab >> 24;
if(Widths)
{
for(j = 0; j < 4; j++, Widths >>= 2)
{
LONG w = Widths & 3;
if(w && (!PutCtrlWord(CWF_STR, rgiszBorders[j + 9]) ||
!PutCtrlWord(CWF_VAL, i_brdrw, 15*w) ||
!PutCtrlWord(CWF_STR, i_brdrs)))
{
return FALSE;
}
}
CheckDelimeter();
}
if(!PutCtrlWord(CWF_VAL, i_cellx, GetTabPos(Tab)))
return FALSE;
}
if(!fPutIntbl || PutCtrlWord(CWF_STR, i_intbl))
return TRUE;
}
return FALSE;
}
/*
* CRTFWrite::PutBorders(fInTable)
*
* @mfunc
* If any borders are defined, output their control words
*
* @rdesc
* error code
*/
EC CRTFWrite::PutBorders(
BOOL fInTable)
{
if(_pPF->wBorderWidth)
{
DWORD Colors = _pPF->dwBorderColor;
DWORD dwEffects = Colors >> 20;
LONG i = 1, iMax = 4; // NonBox for loop limits
LONG j, k;
DWORD Spaces = _pPF->wBorderSpace;
DWORD Styles = _pPF->wBorders;
DWORD Widths = _pPF->wBorderWidth;
if(_pPF->wEffects & PFE_BOX)
i = iMax = 0; // For box, only write one set
for( ; i <= iMax; i++, Spaces >>= 4, Styles >>= 4, Widths >>= 4, Colors >>= 5)
{
if(!(Widths & 0xF)) // No width, so no border
continue;
j = TWIPS_PER_POINT*(Spaces & 0xF);
k = Colors & 0x1F;
if (!PutCtrlWord(CWF_STR, rgiszBorders[i + 4*fInTable]) ||
!PutCtrlWord(CWF_STR, rgiszBorderStyles[Styles & 0xF]) ||
!PutCtrlWord(CWF_VAL, i_brdrw, 10*(Widths & 0xF)) ||
k &&
!PutCtrlWord(CWF_VAL, i_brdrcf, LookupColor(g_Colors[k-1]) + 1) ||
j && !PutCtrlWord(CWF_VAL, i_brsp, j))
{
break;
}
for(j = 3; j--; dwEffects >>= 1) // Output border effects
{
if (dwEffects & 1 &&
!PutCtrlWord(CWF_STR, rgiszBorderEffects[j]))
{
break;
}
}
CheckDelimeter(); // Output a ' '
}
}
return _ecParseError;
}
/*
* CRTFWrite::Puts(sz, cb)
*
* @mfunc
* Put out the string <p sz>
*
* @rdesc
* BOOL TRUE if successful
*/
BOOL CRTFWrite::Puts(
CHAR const * sz,
LONG cb) // @parm String to be put
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::Puts");
if(*sz == '\\' || *sz == '{' || *sz == ' ')
_fNeedDelimeter = FALSE;
CheckDelimeter(); // If _fNeedDelimeter, may need to
// PutChar(' ')
// Flush buffer if string won't fit
if (cb < 0)
return FALSE;
if (_cchBufferOut + cb < _cchBufferOut || (_cchBufferOut + cb >= cachBufferMost && !FlushBuffer()))
return FALSE;
if (cb >= cachBufferMost) // If buffer still can't handle string,
{ // we have to write string directly
LONG cbWritten;
#ifdef DEBUG_PASTE
if (FromTag(tagRTFAsText))
TraceString(sz);
#endif
_pes->dwError = _pes->pfnCallback(_pes->dwCookie,
(LPBYTE) sz, cb, &cbWritten);
_cchOut += cbWritten;
#if defined(DEBUG) && !defined(MACPORT) && !defined(PEGASUS)
if(_hfileCapture)
{
DWORD cbLeftToWrite = cb;
DWORD cbWritten2 = 0;
BYTE *pbToWrite = (BYTE *)sz;
while(WriteFile(_hfileCapture,
pbToWrite,
cbLeftToWrite,
&cbWritten2,
NULL) &&
(pbToWrite += cbWritten2,
(cbLeftToWrite -= cbWritten2)));
}
#endif
if (_pes->dwError)
{
_ecParseError = ecPutCharFailed;
return FALSE;
}
AssertSz(cbWritten == cb,
"CRTFW::Puts: incomplete write");
}
else
{
CopyMemory(_pchRTFEnd, sz, cb); // Put string into buffer for later
_pchRTFEnd += cb; // output
_cchBufferOut += cb;
}
return TRUE;
}
/*
* CRTFWrite::PutCtrlWord(iFormat, iCtrl, iValue)
*
* @mfunc
* Put control word with rgKeyword[] index <p iCtrl> and value <p iValue>
* using format rgszCtrlWordFormat[<p iFormat>]
*
* @rdesc
* TRUE if successful
*
* @devnote
* Sets _fNeedDelimeter to flag that next char output must be a control
* word delimeter, i.e., not alphanumeric (see PutChar()).
*/
BOOL CRTFWrite::PutCtrlWord(
LONG iFormat, // @parm Format index into rgszCtrlWordFormat
LONG iCtrl, // @parm Index into Keyword array
LONG iValue) // @parm Control-word parameter value. If missing,
{ // 0 is assumed
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::PutCtrlWord");
BOOL bRet;
const INT c_chT = 60;
CHAR szT[c_chT];
LONG cb;
cb = sprintF(c_chT,
szT,
rgszCtrlWordFormat[iFormat],
rgKeyword[iCtrl].szKeyword,
iValue);
_fNeedDelimeter = FALSE;
// Truncate if needed
cb = min(cb, c_chT);
bRet = Puts(szT, cb);
_fNeedDelimeter = TRUE; // Ensure next char isn't
// alphanumeric
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -