📄 cfpf.cpp
字号:
return wEffects != wEffectsSave; // Return whether something
} // changed
// Ordinary Style specification
BYTE bLevel = bOutlineLevel;
bOutlineLevel |= 1; // Default not a heading
if(IsHeadingStyle(Style)) // Headings have levels
{ // 0, 2,..., 16, while the
bOutlineLevel = -2*(Style // text that follows has
- STYLE_HEADING_1); // 1, 3,..., 17.
}
if(sStyle == Style && bLevel == bOutlineLevel)
return FALSE; // No change
sStyle = (SHORT)Style;
return TRUE;
}
/*
* CParaFormat::InitDefault(lDefTab, wDefEffects)
*
* @mfunc
* Initialize this CParaFormat with default paragraph formatting
*
* @rdesc
* HRESULT = (if success) ? NOERROR : E_FAIL
*/
HRESULT CParaFormat::InitDefault(LONG lDefTab, WORD wDefEffects)
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CParaFormat::InitDefault");
if(!IsValidParaFormat(this))
return E_FAIL;
AssertSz(cbSize == sizeof(PARAFORMAT2),
"CParaFormat::InitDefault: invalid CParaFormat");
ZeroMemory((LPBYTE)this + cbSkipFormat, sizeof(CParaFormat) - cbSkipFormat);
dwMask = PFM_ALL2;
wAlignment = PFA_LEFT;
sStyle = STYLE_NORMAL; // Default style
wEffects = wDefEffects;
bOutlineLevel = 1; // Default highest text outline
// level
#if lDefaultTab <= 0
#error "default tab (lDefaultTab) must be > 0"
#endif
cTabCount = 1;
if (lDefTab <= 0)
lDefTab = lDefaultTab;
rgxTabs[0] = lDefTab + PFT_DEFAULT;
return NOERROR;
}
#pragma optimize ( "", off )
/*
* CParaFormat::NumToStr(pch, n)
*
* @mfunc
* Convert the list number n to a string taking into consideration
* CParaFormat::wNumbering, wNumberingStart, and wNumberingStyle
*
* @rdesc
* cch of string converted
*/
LONG CParaFormat::NumToStr(
TCHAR * pch, //@parm Target string
LONG n) const //@parm Number + 1 to convert
{
if((wNumberingStyle & 0xF00) == PFNS_NONUMBER)
{
*pch = 0;
return 0; // Number/bullet suppressed
}
if(!n) // Bullet of some kind
{ // CParaFormat::wNumbering
*pch++ = (wNumbering > ' ') // values > ' ' are Unicode
? wNumbering : L'\xB7'; // bullets. Else use bullet
return 1; // in symbol font
}
// Numbering of some kind
// i ii iii iv v vi vii viii ix
static BYTE RomanCode[] = {1, 5, 0x15, 9, 2, 6, 0x16, 0x56, 0xd};
static char RomanLetter[] = "ivxlcdmno";
LONG RomanOffset = 0;
LONG cch = 0; // No chars yet
WCHAR ch = '0'; // Default char code offset
LONG d = 1; // Divisor
LONG r = 10; // Default radix
LONG quot, rem; // ldiv result
LONG Style = (wNumberingStyle << 8) & 0xF0000;
n--; // Convert to number offset
if(Style == tomListParentheses) // Numbering like: (x)
{
cch = 1; // Store leading lparen
*pch++ = '(';
}
if(wNumbering == tomListNumberAsSequence)
ch = wNumberingStart; // Needs generalizations, e.g.,
// appropriate radix
else
{
n += wNumberingStart;
if(IN_RANGE(tomListNumberAsLCLetter, wNumbering, tomListNumberAsUCLetter))
{
ch = (wNumbering == tomListNumberAsLCLetter) ? 'a' : 'A';
if(wNumberingStart >= 1)
n--;
r = 26; // LC or UC alphabetic number
} // Radix 26
}
// GuyBark JupiterJ: Only ever display a single character for katakana lists.
if((wNumbering == tomListNumberAsKatakanaAIUEOdbl) || (wNumbering == tomListNumberAsKatakanaIROHAdbl))
{
// Start with 'A' in katakana.
ch = 0x30A2;
// The use of n here is zero based.
if(wNumberingStart >= 1)
{
n--;
}
// Just cycle round at the end of the katakana.
n %= (wNumbering == tomListNumberAsKatakanaAIUEOdbl ? KATAKANACHARSAIUEOCNT : KATAKANACHARSIROHACNT);
// Display the required katanana character.
*pch++ = (WORD)(ch + (wNumbering == tomListNumberAsKatakanaAIUEOdbl ?
rgKatakanaCharsAIUEO[n] : rgKatakanaCharsIROHA[n]));
cch++;
}
else
{
while(d < n)
{
d *= r; // d = smallest power of r > n
RomanOffset += 2;
}
if(n && d > n)
{
d /= r;
RomanOffset -= 2;
}
while(d)
{
quot = n / d;
rem = n % d;
if(IN_RANGE(tomListNumberAsLCRoman, wNumbering, tomListNumberAsUCRoman))
{
if(quot)
{
n = RomanCode[quot - 1];
while(n)
{
ch = RomanLetter[(n & 3) + RomanOffset - 1];
if(wNumbering == tomListNumberAsUCRoman)
ch &= 0x5F;
*pch++ = ch;
n >>= 2;
cch++;
}
}
RomanOffset -= 2;
}
else
{
n = quot + ch;
if(r == 26 && d > 1) // If alphabetic higher-order
n--; // digit, base it on 'a' or 'A'
*pch++ = (WORD)n; // Store digit
cch++;
}
n = rem; // Setup remainder
d /= r;
}
}
if(Style != tomListPlain) // Trailing text
{ // We only do rparen or period
*pch++ = (Style == tomListPeriod) ? '.' : ')';
cch++;
}
*pch = 0; // Null terminate for RTF writer
return cch;
}
#pragma optimize ( "", on)
/*
* CParaFormat::Set(pPF)
*
* @mfunc
* Copy *<p pPF> to this CParaFormat
*
* @devnote
* *<p pPF> is an external PARAFORMAT or PARAFORMAT2 with the
* appropriate size given by cbSize. But this CParaFormat is internal
* and cbSize is used as a reference count.
*/
void CParaFormat::Set (
const PARAFORMAT *pPF) //@parm PARAFORMAT to copy to this CParaFormat
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CParaFormat::Set");
UINT cb = pPF->cbSize;
// Protect against overflow
ASSERT(cb <= sizeof(CParaFormat));
if(cb > sizeof(CParaFormat))
{
return;
}
CopyFormat(this, pPF, cb);
if(cb < sizeof(CParaFormat))
ZeroMemory((LPBYTE)this + cb, sizeof(CParaFormat) - cb);
}
/*
* CParaFormat::UpdateNumber(n, pPF)
*
* @mfunc
* Return new value of number for paragraph described by this PF
* following a paragraph described by pPF
*
* @rdesc
* New number for paragraph described by this PF
*/
LONG CParaFormat::UpdateNumber (
LONG n, //@parm Current value of number
const CParaFormat *pPF) const //@parm Previous CParaFormat
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CParaFormat::UpdateNumber");
if(!IsListNumbered())
return 0; // No numbering
if(IsNumberSuppressed())
return n; // Number is suppressed, so no change
if (!pPF || wNumbering != pPF->wNumbering ||
(wNumberingStyle != pPF->wNumberingStyle && !pPF->IsNumberSuppressed()) ||
wNumberingStart != pPF->wNumberingStart)
{ // Numbering type or style
return 1; // changed, so start over
}
return n + 1; // Same kind of numbering,
}
//------------------------- Helper Functions -----------------------------------
// Defines and fixed font size details for increasing/decreasing font size
#define PWD_FONTSIZEPOINTMIN 1
// The following corresponds to the max signed 2-byte TWIP value, (32760)
#define PWD_FONTSIZEPOINTMAX 1638
typedef struct tagfsFixup
{
BYTE EndValue;
BYTE Delta;
}
FSFIXUP;
const FSFIXUP fsFixups[] =
{
12, 1,
28, 2,
36, 0,
48, 0,
72, 0,
80, 0,
0, 10 // EndValue = 0 case is treated as "infinite"
};
#define PWD_FONTSIZEMAXFIXUPS (sizeof(fsFixups)/sizeof(fsFixups[0]))
/*
* GetUsableFontHeight(ySrcHeight, lPointChange)
*
* @func
* Return a font size for setting text or insertion point attributes
*
* @rdesc
* New TWIPS height
*
* @devnote
* Copied from WinCE RichEdit code (written by V-GUYB)
*/
LONG GetUsableFontHeight(
LONG ySrcHeight, //@parm Current font size in twips
LONG lPointChange) //@parm Increase in pt size, (-ve if shrinking)
{
LONG EndValue;
LONG Delta;
int i;
LONG yRetHeight;
// Input height in twips here, (TWentIeths of a Point).
// Note, a Point is a 1/72th of an inch. To make these
// calculations clearer, use point sizes here. Input height
// in twips is always divisible by 20 (NOTE (MS3): maybe with
// a truncation, since RTF uses half-point units).
yRetHeight = (ySrcHeight / 20) + lPointChange;
// Fix new font size to match sizes used by Word95
for(i = 0; i < PWD_FONTSIZEMAXFIXUPS; ++i)
{
EndValue = fsFixups[i].EndValue;
Delta = fsFixups[i].Delta;
// Does new height lie in this range of point sizes?
if(yRetHeight <= EndValue || !EndValue)
{
// If new height = EndValue, then it doesn't need adjusting
if(yRetHeight != EndValue)
{
// Adjust new height to fit this range of point sizes. If
// Delta = 1, all point sizes in this range stay as they are.
if(!Delta)
{
// Everything in this range is rounded to the EndValue
yRetHeight = fsFixups[(lPointChange > 0 ?
i : max(i - 1, 0))].EndValue;
}
else if(Delta != 1)
{
// Round new height to next delta in this range
yRetHeight = ((yRetHeight +
(lPointChange > 0 ? Delta - 1 : 0))
/ Delta) * Delta;
}
}
break;
}
}
// Limit the new text size. Note, if we fix the text size
// now, then we won't take any special action if we change
// the text size later in the other direction. For example,
// we shrink chars with size 1 and 2. They both change to
// size 1. Then we grow them both to 2. So they are the
// same size now, even though they weren't before. This
// matches Word95 behavior.
yRetHeight = max(yRetHeight, PWD_FONTSIZEPOINTMIN);
yRetHeight = min(yRetHeight, PWD_FONTSIZEPOINTMAX);
return yRetHeight*20; // Return value in twips
}
/*
* IsValidCharFormat(pCF)
*
* @func
* Return TRUE iff the structure *<p pCF> has the correct size to be
* a CHARFORMAT or a CHARFORMAT2
*
* @rdesc
* Return TRUE if *<p pCF> is a valid CHARFORMAT(2)
*/
BOOL IsValidCharFormat (
const CHARFORMAT * pCF) //@parm CHARFORMAT to validate
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "IsValidCharFormat");
if (pCF && (pCF->cbSize == sizeof(CHARFORMAT) ||
pCF->cbSize == sizeof(CHARFORMAT2)))
{
return TRUE;
}
TRACEERRORSZ("!!!!!!!!!!! bogus CHARFORMAT from client !!!!!!!!!!!!!");
return FALSE;
}
/*
* IsValidCharFormatA(pCFA)
*
* @func
* Return TRUE iff the structure *<p pCF> has the correct size to be
* a CHARFORMATA or a CHARFORMAT2A
*
* @rdesc
* Return TRUE if *<p pCF> is a valid CHARFORMAT(2)A
*/
BOOL IsValidCharFormatA (
const CHARFORMATA * pCFA) //@parm CHARFORMATA to validate
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "IsValidCharFormatA");
if (pCFA && (pCFA->cbSize == sizeof(CHARFORMATA) ||
pCFA->cbSize == sizeof(CHARFORMAT2A)))
{
return TRUE;
}
TRACEERRORSZ("!!!!!!!!!!! bogus CHARFORMATA from client !!!!!!!!!!!!!");
return FALSE;
}
/*
* IsValidParaFormat(pPF)
*
* @func
* Return TRUE iff the structure *<p pPF> has the correct size to be
* a PARAFORMAT or a PARAFORMAT2
*
* @rdesc
* Return TRUE if *<p pPF> is a valid PARAFORMAT(2)
*/
BOOL IsValidParaFormat (
const PARAFORMAT * pPF) //@parm PARAFORMAT to validate
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "IsValidParaFormat");
if (pPF && (pPF->cbSize == sizeof(PARAFORMAT) ||
pPF->cbSize == sizeof(PARAFORMAT2)))
{
return TRUE;
}
TRACEERRORSZ("!!!!!!!!!!! bogus PARAFORMAT from client !!!!!!!!!!!!!");
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -