📄 rtfwrit2.cpp
字号:
// iRet = PFN_SUCCESS; (done above)
}
else // chTemp == 0
{
UnexpectedChar:
Assert(!chTemp);
// fSetCharSet = FALSE; (done above)
iRet = PFN_FAIL;
}
// we had to at least get a font name out of this
if(!**pszName)
{
iRet = PFN_FAIL;
}
// advance past the delimiter (or NULL char if malformed buffer)
Assert(chTemp == chDelimiter || iRet != PFN_SUCCESS && chTemp == TEXT('\0'));
pchBuf++;
*ppchBufNew = pchBuf;
return iRet;
}
/*
* CRTFConverter::FontSubstitute(szTaggedName, szNormalName, pbCharSet)
*
* Purpose:
* Verify that szTaggedName is szNormalName plus char set tag
* If yes than write corresponding charSet tp pbCharSet
*
* Arguments:
* szTaggedName name with tag
* szNormalName name without tag
* pbcharSEt where to write char set
*
*
* Returns:
* BOOL
*/
BOOL CRTFConverter::FontSubstitute(TCHAR *szTaggedName, TCHAR *szNormalName, BYTE *pbCharSet)
{
const NTCSENTRY *pszcs = mpszcs;
Assert(szTaggedName);
Assert(szNormalName);
Assert(pbCharSet);
Assert(*szTaggedName);
// ensure same name, except for prefix
while(*szNormalName == *szTaggedName)
{
*szNormalName++;
*szTaggedName++;
}
// verify that we have reached the end of szNormalName
while(*szNormalName)
{
if(*szNormalName != TEXT(' ') && *szNormalName != TAB)
{
return FALSE;
}
szNormalName++;
}
szTaggedName++;
while(pszcs->bCharSet)
{
if(!_wcsicmp(szTaggedName, pszcs->szLocaleName))
{
*pbCharSet=pszcs->bCharSet;
return TRUE;
}
pszcs++;
}
#if defined(DEBUG) && !defined(PEGASUS)
char szBuf[MAX_PATH];
char szTag[256];
WideCharToMultiByte(CP_ACP, 0, szTaggedName, -1, szTag, sizeof(szTag),
NULL, NULL);
sprintf(szBuf, "CRTFConverter::FontSubstitute(): Unrecognized tag found at"
" end of tagged font name - \"%s\" (Raid this asap)", szTag);
TRACEWARNSZ(szBuf);
#endif
return FALSE;
}
/*
* CRTFConverter::FindTaggedFont(const char *szNormalName, BYTE bCharSet, char **ppchTaggedName)
*
* Purpose:
* Find font name may be with additional special tag corresponding to szNormalName & bCharSet
*
* Arguments:
* szNormalName font name in RTF
* bCharSet RTF char set
* ppchTaggedName where to write tagged name
*
* Returns:
* BOOL TRUE if find
*/
BOOL CRTFConverter::FindTaggedFont(const TCHAR *szNormalName, BYTE bCharSet, TCHAR **ppchTaggedName)
{
int itfi;
if(!_rgtfi)
return FALSE;
for(itfi = 0; itfi < _ctfi; itfi++)
{
if(_rgtfi[itfi].bCharSet == bCharSet &&
!_wcsicmp(szNormalName, _rgtfi[itfi].szNormalName))
{
*ppchTaggedName = _rgtfi[itfi].szTaggedName;
return TRUE;
}
}
return FALSE;
}
/*
* CRTFConverter::IsTaggedFont(const char *szName, BYTE *pbCharSet, char **ppchNormalName)
*
* Purpose:
* Figure out is szName font name with additional tag corresponding to pbCharSet
* If no charset specified, still try to match and return the correct charset
*
* Arguments:
* szNormalName font name in RTF
* bCharSet RTF char set
* ppchNormalName where to write normal name
*
* Returns:
* BOOL TRUE if is
*/
BOOL CRTFConverter::IsTaggedFont(const TCHAR *szName, BYTE *pbCharSet, TCHAR **ppchNormalName)
{
int itfi;
if(!_rgtfi)
return FALSE;
for(itfi = 0; itfi < _ctfi; itfi++)
{
if((*pbCharSet <= 1 || _rgtfi[itfi].bCharSet == *pbCharSet) &&
!lstrcmpi(szName, _rgtfi[itfi].szTaggedName))
{
*pbCharSet = _rgtfi[itfi].bCharSet;
*ppchNormalName = _rgtfi[itfi].szNormalName;
return TRUE;
}
}
return FALSE;
}
/*
* CRTFWrite::WriteData(pbBuffer, cbBuffer)
*
* Purpose:
* Write out object data. This must be called only after all
* initial object header information has been written out.
*
* Arguments:
* pbBuffer pointer to write buffer
* cbBuffer number of bytes to write out
*
* Returns:
* LONG number of bytes written out
*/
LONG CRTFWrite::WriteData(BYTE * pbBuffer, LONG cbBuffer)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteData");
LONG cb = 0;
BYTE bT;
_fNeedDelimeter = FALSE;
while(cb < cbBuffer )
{
bT = *pbBuffer++; // Put out hex value of byte
PutChar(szHexDigits[bT >> 4]); // Store high nibble
PutChar(szHexDigits[bT & 15]); // Store low nibble
// Every 78 chars and at end of group, drop a line
if (!(++cb % 39) || (cb == cbBuffer))
Puts(szLineBreak, sizeof(szLineBreak) - 1);
}
return cb;
}
/*
* CRTFWrite::WriteBinData(pbBuffer, cbBuffer)
*
* Purpose:
* Write out object binary data. This must be called only after all
* initial object header information has been written out.
*
* Arguments:
* pbBuffer pointer to write buffer
* cbBuffer number of bytes to write out
*
* Returns:
* LONG number of bytes written out
*/
LONG CRTFWrite::WriteBinData(BYTE * pbBuffer, LONG cbBuffer)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteData");
LONG cb = 0;
BYTE bT;
_fNeedDelimeter = FALSE;
while(cb < cbBuffer )
{
bT = *pbBuffer++;
if (!PutChar(bT))
break;
cb++;
}
return cb;
}
/*
* CRTFWrite::WriteRtfObject(prtfObject, fPicture)
*
* Purpose:
* Writes out an picture or object header's render information
*
* Arguments:
* prtfObject The object header information
* fPicture Is this a header for a picture or an object
*
* Returns:
* EC The error code
*
* Comments:
* Eventually use keywords from rtf input list rather than partially
* creating them on the fly
*/
EC CRTFWrite::WriteRtfObject(RTFOBJECT & rtfObject, BOOL fPicture)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteRtfObject");
LONG i;
LONG * pDim;
const WORD * pKeyWordIndex;
if(fPicture)
{
pKeyWordIndex = PictureKeyWordIndexes;
pDim = &rtfObject.xExtPict;
}
else
{
pKeyWordIndex = ObjectKeyWordIndexes;
pDim = &rtfObject.xExt;
}
//Extents
for(i = 2; i--; pDim++, pKeyWordIndex++)
{
if (*pDim )
PutCtrlWord(CWF_VAL, *pKeyWordIndex, (SHORT)*pDim);
}
// Scaling
pDim = &rtfObject.xScale;
for(i = 2; i--; pDim++, pKeyWordIndex++)
{
if (*pDim && *pDim != 100 )
PutCtrlWord(CWF_VAL, *pKeyWordIndex, (SHORT)*pDim);
}
// Cropping
pDim = &rtfObject.rectCrop.left;
for(i = 4; i--; pDim++, pKeyWordIndex++)
{
if (*pDim )
PutCtrlWord(CWF_VAL, *pKeyWordIndex, (SHORT)*pDim);
}
return _ecParseError;
}
/*
* CRTFWrite::WritePicture(REOBJECT &reObject,RTFOBJECT & rtfObject)
*
* Purpose:
* Writes out an picture's header as well as the object's data.
*
* Arguments:
* reObject Information from GetObject
* prtfObject The object header information
*
* Returns:
* EC The error code
*
* Note:
* *** Writes only metafiles ***
*/
EC CRTFWrite::WritePicture(REOBJECT &reObject,RTFOBJECT & rtfObject)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WritePicture");
_ecParseError = ecStreamOutObj;
// Start and write picture group
PutCtrlWord( CWF_GRP, i_pict );
// Write that this is metafile
PutCtrlWord( CWF_VAL, i_wmetafile, rtfObject.sPictureType );
// Write picture render details
WriteRtfObject( rtfObject, TRUE );
// Write goal sizes
if (rtfObject.xExtGoal )
PutCtrlWord ( CWF_VAL, i_picwgoal, rtfObject.xExtGoal );
if (rtfObject.yExtGoal )
PutCtrlWord (CWF_VAL, i_pichgoal, rtfObject.yExtGoal);
// Start picture data
Puts( szLineBreak, sizeof(szLineBreak) - 1 );
// Write out the data
if ((UINT) WriteData( rtfObject.pbResult, rtfObject.cbResult ) != rtfObject.cbResult)
{
goto CleanUp;
}
_ecParseError = ecNoError;
CleanUp:
PutChar( chEndGroup ); // End picture data
return _ecParseError;
}
/*
* CRTFWrite::WriteDib(REOBJECT &reObject,RTFOBJECT & rtfObject)
*
* Purpose:
* Writes out an DIB primarily for Win CE
*
* Arguments:
* reObject Information from GetObject
* prtfObject The object header information
*
* Returns:
* EC The error code
*
* Note:
* *** Writes only dibs ***
*/
EC CRTFWrite::WriteDib(REOBJECT &reObject,RTFOBJECT & rtfObject)
{
TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WritePicture");
LPBITMAPINFO pbmi = (LPBITMAPINFO) rtfObject.pbResult;
_ecParseError = ecStreamOutObj;
// ************** V-GUYB: Add this for converting pictures to 2bpp during stream out.
// Store the original values so we can restore them on exit.
LPBYTE pbResult = rtfObject.pbResult;
ULONG cbResult = rtfObject.cbResult;
HGLOBAL hMem2bpp = 0;
#if defined(CONVERT2BPP)
// Pictures must be saved as 2bpp if saving to PWord V1 format.
if((_dwFlags & SFF_PWD) && ((_dwFlags & SFF_RTFVAL) >> 16 == 0))
{
if(pbmi->bmiHeader.biBitCount > PWDV1_BPP)
{
HWND hWnd;
HDC hdc, hdcSrc, hdcDst;
HBITMAP hdibSrc, hdibDst;
LPBYTE pbDibSrc, pbDibDst;
BMI2BPP bmi2bpp = {0};
int iOffset, nBytes;
// First get a dc with the source dib in it.
hWnd = GetDesktopWindow();
hdc = GetDC(hWnd);
hdcSrc = CreateCompatibleDC(hdc);
if(!hdcSrc)
{
ReleaseDC(hWnd, hdc);
_ecParseError = ecNoMemory;
goto leave;
}
// Using CreateDIBSection below ensures that the working dibs and dcs will get a
// bpp of the appropriate dib, not a bpp based on the bpp of the device display.
if((hdibSrc = CreateDIBSection(hdcSrc, pbmi, DIB_RGB_COLORS, (void**)&pbDibSrc, NULL, 0)))
{
SelectObject(hdcSrc, hdibSrc);
// Get an offset to the source bits.
iOffset = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * (1<<pbmi->bmiHeader.biBitCount));
memcpy(pbDibSrc, &rtfObject.pbResult[iOffset], rtfObject.cbResult - iOffset);
// Now, build up a BITMAPINFO appropriate for a 2bpp dib.
bmi2bpp.bmih = pbmi->bmiHeader;
bmi2bpp.bmih.biBitCount = PWDV1_BPP;
// Add the 4 color color-table.
memcpy(bmi2bpp.colors, (RGBQUAD*)ColorTable2bpp, (1<<PWDV1_BPP) * sizeof(RGBQUAD));
// Now create the new dib.
hdcDst = CreateCompatibleDC(hdc);
if((hdibDst = CreateDIBSection(hdcDst, (BITMAPINFO*)&bmi2bpp, DIB_RGB_COLORS, (void**)&pbDibDst, NULL, 0)))
{
SelectObject(hdcDst, hdibDst);
// Blit the > 2bpp dib into the 2bpp dib and let the system do the color mapping.
BitBlt(hdcDst, 0, 0, bmi2bpp.bmih.biWidth, bmi2bpp.bmih.biHeight, hdcSrc, 0, 0, SRCCOPY);
// Calculate the new bytes per line for the 2bpp dib.
rtfObject.cBytesPerLine = (((bmi2bpp.bmih.biWidth * PWDV1_BPP) + 31) & ~31) / 8; // DWORD boundary.
// Get the new size of the 2bpp byte array.
nBytes = rtfObject.cBytesPerLine * bmi2bpp.bmih.biHeight;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -