📄 cfpf.cpp
字号:
}
/*
* CCharFormat::Get(pCF)
*
* @mfunc
* Copy this CCharFormat to *<p pCF>
*
* @devnote
* *<p pCF> is an external CCharFormat, i.e., it represents either a
* CHARFORMAT or a CHARFORMAT2 with the appropriate size given by
* cbSize. But this CCharFormat is internal and cbSize is used as
* a reference count.
*/
void CCharFormat::Get (
CCharFormat *pCF) const //@parm CCharFormat to copy this CCharFormat to
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::Get");
UINT cb = pCF->cbSize;
pCF->dwMask = CFM_ALL2; // Default CHARFORMAT2
if(cb != sizeof(CHARFORMAT2)) // It isn't
{
pCF->dwMask = CFM_ALL; // Use CHARFORMAT
ASSERT(cb == sizeof(CHARFORMAT)); // It better be a CHARFORMAT
}
// Bound the copy
cb = min(cb, sizeof(CCharFormat));
CopyFormat(pCF, this, cb); // Copy this to pCF
pCF->wInternalFlags = wInternalFlags;
}
/*
* CCharFormat::GetA(pCFA)
*
* @mfunc
* Copy this UNICODE character format (including its dwMask) to an ANSI
* CHARFORMAT *pCFA with size given by pCFA->cbSize.
*
* @rdesc
* TRUE if successful; else FALSE
*/
BOOL CCharFormat::GetA(CHARFORMATA *pCFA) const
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::GetA");
if(!IsValidCharFormatA(pCFA))
return FALSE;
// Copy from dwMask up to szFaceName
CopyMemory((BYTE *)pCFA + sizeof(DWORD), (BYTE *)this + sizeof(DWORD),
(BYTE *)&szFaceName[0] - (BYTE *)&dwMask);
if(bInternalEffects & CFEI_FACENAMEISDBCS)
{
// HACK: The face name is actually DBCS stuffed into the unicode
// buffer, so simply un-stuff this DBCS into the ANSI string
TCHAR *pchSrc = const_cast<TCHAR *>(szFaceName);
char *pachDst = pCFA->szFaceName;
UINT i=0;
while(i<(LF_FACESIZE-1) && pchSrc[i])
{
pachDst[i] = pchSrc[i];
i++;
}
pachDst[i] = 0;
}
else
{
// We have to use CP_ACP to convert font name. We used to
// use GetLocaleCodePage() which would cause problem in FE system using
// non-FE locale. e.g. Win95Trad.Chinese with US English regional setting.
MbcsFromUnicode( pCFA->szFaceName, LF_FACESIZE, szFaceName, -1, CP_ACP,
UN_NOOBJECTS);
}
if(pCFA->cbSize == sizeof(CHARFORMATA))
{
pCFA->dwEffects &= CFM_EFFECTS; // We're done. Don't return more
pCFA->dwMask &= CFM_ALL; // info than requested (for
} // backward compatibility)
else
CopyMemory(&((CHARFORMAT2A *)pCFA)->wWeight, &wWeight, CHARFORMATDELTA);
return TRUE;
}
/*
* CCharFormat::InitDefault(hfont)
*
* @mfunc
* Initialize this CCharFormat with information coming from the font
* <p hfont>
*
* @rdesc
* HRESULT = (if success) ? NOERROR : E_FAIL
*/
HRESULT CCharFormat::InitDefault (
HFONT hfont) //@parm Handle to font info to use
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::InitDefault");
LOGFONT lf;
if(!IsValidCharFormat(this))
return E_FAIL;
ZeroMemory((LPBYTE)this + cbSkipFormat, cbSize - cbSkipFormat);
bCRC = 0;
// If hfont isn't defined, get LOGFONT for default font
if (!hfont)
hfont = (HFONT)GetStockObject(SYSTEM_FONT);
// Get LOGFONT for passed hfont
if (!W32->GetObject(hfont, sizeof(LOGFONT), &lf))
return E_FAIL;
/* COMPATIBILITY ISSUE:
* RichEdit 1.0 selects hfont into a screen DC, gets the TEXTMETRIC,
* and uses tm.tmHeight - tm.tmInternalLeading instead of lf.lfHeight
* in the following. The following is simpler and since we have broken
* backward compatibility on line/page breaks, I've left it (murrays).
*/
yHeight = (lf.lfHeight * LY_PER_INCH) / sysparam.GetYPerInchScreenDC();
if(yHeight < 0)
yHeight = -yHeight;
#ifdef MACPORTStyle
dwEffects = (CFM_EFFECTS | CFE_AUTOBACKCOLOR | CFE_OUTLINE | CFE_SHADOW) & ~(CFE_PROTECTED | CFE_LINK);
#else
dwEffects = (CFM_EFFECTS | CFE_AUTOBACKCOLOR) & ~(CFE_PROTECTED | CFE_LINK);
#endif
dwMask = CFM_ALL2; // In case default gets
// Apply()'d
if(lf.lfWeight < FW_BOLD)
dwEffects &= ~CFE_BOLD;
#ifdef MACPORTStyle
if(!(lf.lfWeight & FW_OUTLINE))
dwEffects &= ~CFE_OUTLINE;
if (!(lf.lfWeight & FW_SHADOW))
dwEffects &= ~CFE_SHADOW;
#endif
if(!lf.lfItalic)
dwEffects &= ~CFE_ITALIC;
if(!lf.lfUnderline)
dwEffects &= ~CFE_UNDERLINE;
if(!lf.lfStrikeOut)
dwEffects &= ~CFE_STRIKEOUT;
wWeight = (WORD)lf.lfWeight;
lcid = GetSystemDefaultLCID();
bCharSet = lf.lfCharSet;
bPitchAndFamily = lf.lfPitchAndFamily;
wcscpy(szFaceName, lf.lfFaceName);
bUnderlineType = CFU_UNDERLINE; // Default solid underlines
// Are gated by CFE_UNDERLINE
SetCRC();
wInternalFlags = 0;
return NOERROR;
}
/*
* CCharFormat::Set(pCF)
*
* @mfunc
* Copy *<p pCF> to this CCharFormat
*
* @devnote
* *<p pCF> is an external CHARFORMAT or CHARFORMAT2 with the
* appropriate size given by cbSize. But this CCharFormat is internal
* and cbSize is used as a reference count. Note: this differs from
* Apply() in that it copies data without checking the dwMask bits.
*/
void CCharFormat::Set (
const CHARFORMAT *pCF) //@parm CHARFORMAT to copy to this CCharFormat
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::Set");
UINT cb = pCF->cbSize;
// Protect against overflow
ASSERT(cb <= sizeof(CCharFormat));
if(cb > sizeof(CCharFormat))
{
return;
}
CopyFormat(this, pCF, cb);
ZeroMemory((LPBYTE)this + cb, sizeof(CCharFormat) - cb);
if(cb < sizeof(CHARFORMAT2)) // Use defaults for CHARFORMAT
{
dwEffects |= CFE_AUTOBACKCOLOR;
bUnderlineType = CFU_UNDERLINE;
}
SetCRC(); // Set the CRC for rapid Finds
}
/*
* CCharFormat::Set(pCF)
*
* @mfunc
* Copy *<p pCF> to this CCharFormat
*
* @devnote
* This function also copies the data members of CCharFormat (in addition
* to those of CHARFORMAT and CHARFORMAT2
*/
void CCharFormat::Set(const CCharFormat *pCF)
{
*this = *pCF;
SetCRC();
}
/*
* CCharFormat::SetA(pCFA)
*
* @mfunc
* Copy the ANSI CHARFORMATA *<p pCFA> (including pCFA->dwMask) to this
* UNICODE character format structure
*
* @rdesc
* TRUE if successful; else FALSE
*/
BOOL CCharFormat::SetA(
CHARFORMATA *pCFA) //@parm CHARFORMATA to apply to this CF
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::SetA");
if(!IsValidCharFormatA(pCFA))
return FALSE;
// Copy from dwMask up to szFaceName
CopyMemory((BYTE *)this + sizeof(DWORD), (BYTE *)pCFA + sizeof(DWORD),
offsetof(CHARFORMAT, szFaceName) - sizeof(DWORD));
// should this code change such that we pass a code page to UnicodeFromMbcs
// which isn't guaranteed to be on the system, we should change this code so
// that we stuff the DBCS char's into the wchar buffer (see rtfread.cpp)
// We have to use CP_ACP to convert font name. We used to
// use GetLocaleCodePage() which would cause problem in FE system using
// non-FE locale. e.g. Win95Trad.Chinese with US English regional setting.
if(pCFA->dwMask & CFM_FACE)
UnicodeFromMbcs(szFaceName, LF_FACESIZE, pCFA->szFaceName, LF_FACESIZE,
CP_ACP);
if(pCFA->cbSize == sizeof(CHARFORMATA))
{
// ignore CHARFORMAT2 adds, but set our size to the UNICODE version
cbSize = sizeof(CHARFORMATW);
dwMask &= CFM_ALL;
}
else if (pCFA->dwMask & ~CFM_ALL)
{
// better have been an ansi 2.0 structure
Assert(pCFA->cbSize == sizeof(CHARFORMAT2A));
CopyMemory(&wWeight, &((CHARFORMAT2A *)pCFA)->wWeight, CHARFORMATDELTA);
}
SetCRC();
wInternalFlags = 0;
return TRUE;
}
/*
* CCharFormat::SetCRC()
*
* @mfunc
* For fast font cache lookup, calculate CRC.
*
* @devnote
* The font cache stores anything that has to
* do with measurement of metrics. Any font attribute
* that does not affect this should NOT be counted
* in the CRC; things like underline and color are not counted.
*/
void CCharFormat::SetCRC()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::SetCRC");
BYTE bCrc = 0;
BYTE* pb;
BYTE * pend = (BYTE*)&yOffset;
TCHAR *pFaceName;
for (pb = (BYTE*)&dwEffects; pb < pend; pb++)
bCrc ^= *pb;
pend = (BYTE*)&szFaceName;
for (pb = (BYTE*)&bCharSet; pb < pend; pb++)
bCrc ^= *pb;
pend = (BYTE*)&szFaceName + sizeof(szFaceName);
for (pb = (BYTE*)&szFaceName, pFaceName = (TCHAR *)&szFaceName;
*pFaceName && pb < pend; pFaceName++)
{
bCrc ^= *pb++;
bCrc ^= *pb++;
}
if (!bCrc ) bCrc++; // 0 is reserved for not set.
this->bCRC = bCrc;
}
//------------------------- CParaFormat Class -----------------------------------
CParaFormat::CParaFormat()
{
cbSize = sizeof(PARAFORMAT2);
dwBorderColor = 0;
//dwMask2 = 0; // For further extensions...
}
/*
* CParaFormat::AddTab(tbPos, tbAln, tbLdr)
*
* @mfunc
* Add tabstop at position <p tbPos>, alignment type <p tbAln>, and
* leader style <p tbLdr>
*
* @rdesc
* (success) ? NOERROR : S_FALSE
*
* @devnote
* Tab struct that overlays LONG in internal rgxTabs is
*
* DWORD tabPos : 24;
* DWORD tabType : 4;
* DWORD tabLeader : 4;
*/
HRESULT CParaFormat::AddTab (
LONG tbPos, //@parm New tab position
LONG tbAln, //@parm New tab alignment type
LONG tbLdr, //@parm New tab leader style
BOOL fInTable) //@parm True if simulating cells
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CParaFormat::AddTab");
if (!fInTable &&
((DWORD)tbAln > tomAlignBar || // Validate arguments
(DWORD)tbLdr > tomLines || // Comparing DWORDs causes
(DWORD)tbPos > 0xffffff || !tbPos)) // negative values to be
{ // treated as invalid
return E_INVALIDARG;
}
LONG iTab;
LONG tbPosCurrent;
LONG tbValue = tbPos + (tbAln << 24) + (tbLdr << 28);
if((rgxTabs[0] & PFT_DEFAULT) == PFT_DEFAULT) // If 1st tab is default
cTabCount = 0; // tab, delete it
for(iTab = 0; iTab < cTabCount && // Determine where to
tbPos > GetTabPos(rgxTabs[iTab]); // insert new tabstop
iTab++) ;
if(iTab < MAX_TAB_STOPS)
{
tbPosCurrent = GetTabPos(rgxTabs[iTab]);
if(iTab == cTabCount || tbPosCurrent != tbPos)
{
MoveMemory(&rgxTabs[iTab + 1], // Shift array up
&rgxTabs[iTab], // (unless iTab = Count)
(cTabCount - iTab)*sizeof(LONG));
if(cTabCount < MAX_TAB_STOPS) // If there's room,
{
rgxTabs[iTab] = tbValue; // store new tab stop,
cTabCount++; // increment tab count,
return NOERROR; // signal no error
}
}
else if(tbPos == tbPosCurrent) // Update tab since leader
{ // style or alignment may
rgxTabs[iTab] = tbValue; // have changed
return NOERROR;
}
}
return S_FALSE;
}
/*
* CParaFormat::Apply(pPF)
*
* @mfunc
* Apply *<p pPF> to this CParaFormat as specified by nonzero bits in
* <p pPF>->dwMask
*/
HRESULT CParaFormat::Apply (
const CParaFormat *pPF) //@parm CParaFormat to apply to this PF
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CParaFormat::Apply");
const DWORD dwMaskApply = pPF->dwMask;
BOOL fPF = pPF->cbSize == sizeof(PARAFORMAT);
WORD wEffectMask;
if(dwMaskApply & PFM_NUMBERING)
wNumbering = pPF->wNumbering;
if(dwMaskApply & PFM_STARTINDENT)
dxStartIndent = pPF->dxStartIndent;
else if(dwMaskApply & PFM_OFFSETINDENT)
dxStartIndent += pPF->dxStartIndent;
if(dwMaskApply & PFM_OFFSET)
dxOffset = pPF->dxOffset;
if(dwMaskApply & PFM_RIGHTINDENT)
dxRightIndent = pPF->dxRightIndent;
if(dwMaskApply & PFM_ALIGNMENT)
{
wAlignment = pPF->wAlignment;
if(!fPF && (wAlignment < PFA_LEFT || wAlignment > PFA_JUSTIFY))
{
TRACEERRORSZ("CParaFormat::Apply: invalid Alignment");
return E_INVALIDARG;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -