📄 cfpf.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
* @doc INTERNAL
*
* @module CFPF.C -- -- RichEdit CCharFormat and CParaFormat Classes |
*
* Created: <nl>
* 9/1995 -- Murray Sargent <nl>
*
* @devnote
* The this ptr for all methods points to an internal format class, i.e.,
* either a CCharFormat or a CParaFormat, which uses the cbSize field as
* a reference count. The pCF or pPF argument points at an external
* CCharFormat or CParaFormat class, that is, pCF->cbSize and pPF->cbSize
* give the size of their structure. The code still assumes that both
* internal and external forms are derived from the CHARFORMAT(2) and
* PARAFORMAT(2) API structures, so some redesign would be necessary to
* obtain a more space-efficient internal form.
*
*/
#include "_common.h"
#include "_array.h" // for fumemmov()
#include "_rtfconv.h" // for IsCharSetValid()
ASSERTDATA
// Table of formatting info for Normal and Heading styles
const STYLEFORMAT g_Style[] = // {dwEffects; yHeight}
{ // Measurements in points
{CFE_BOLD, 14}, // Heading 1
{CFE_BOLD + CFE_ITALIC, 12}, // Heading 2
{0, 12}, // Heading 3
{CFE_BOLD, 12}, // Heading 4
{0, 11}, // Heading 5
{CFE_ITALIC, 11}, // Heading 6
{0, 0}, // Heading 7
{CFE_ITALIC, 0}, // Heading 8
{CFE_BOLD + CFE_ITALIC, 9} // Heading 9
};
// GuyBark JupiterJ: Offsets for the characters that appear in ordered Katakana lists.
const BYTE rgKatakanaCharsAIUEO[] =
{
0, 2, 4, 6, 8,
9, 11, 13, 15, 17,
19, 21, 23, 25, 27,
29, 31, 34, 36, 38,
40, 41, 42, 43, 44,
45, 48, 51, 54, 57,
60, 61, 62, 63, 64,
66, 68, 70,
71, 72, 73, 74, 75,
77, 80,
81
};
#define KATAKANACHARSAIUEOCNT (sizeof(rgKatakanaCharsAIUEO) / sizeof(BYTE))
// Offsets for the characters that appear in poem-based Katakana lists.
const BYTE rgKatakanaCharsIROHA[] =
{
2, 75, 45, 41, 57,
54, 38, 31, 72, 42,
73, 80, 77, 9, 70,
29, 74, 27, 34, 43,
40, 71, 62, 4, 78,
44, 8, 13, 66, 60,
15, 51, 17, 6, 36,
0, 19, 11, 68, 63,
61, 21, 79, 48, 64,
25, 23, 81
};
#define KATAKANACHARSIROHACNT (sizeof(rgKatakanaCharsIROHA) / sizeof(BYTE))
//------------------------- CCharFormat Class -----------------------------------
CCharFormat::CCharFormat()
{
cbSize = sizeof(CHARFORMAT2);
wInternalFlags = 0;
}
/*
* CCharFormat::Apply(pCF)
*
* @mfunc
* Apply *<p pCF> to this CCharFormat as specified by nonzero bits in
* <p pCF>->dwMask
*
* @devnote
* Autocolor is dealt with through a neat little hack made possible
* by the choice CFE_AUTOCOLOR = CFM_COLOR (see richedit.h). Hence
* if <p pCF>->dwMask specifies color, it automatically resets autocolor
* provided (<p pCF>->dwEffects & CFE_AUTOCOLOR) is zero.
*
* *<p pCF> is an external CCharFormat, i.e., it's 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.
*/
HRESULT CCharFormat::Apply (
const CCharFormat *pCF, //@parm CCharFormat to apply to this CF
BOOL bInOurHost)
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::Apply");
DWORD dwEffectMask;
const DWORD dwMaskApply = pCF->dwMask;
BOOL fCF;
if(pCF->cbSize == sizeof(CHARFORMAT))
{
fCF = TRUE;
dwEffectMask = dwMaskApply & CFM_EFFECTS;
// or'ing in CFM_DISABLED in this manner is incredibly lame
// and prone to compatibility problems. However, the Forms^3
// team has decided _not_ to use CharFormat2's even though
// they explicitly asked for the feature in the first place.
// go figure.
if (!bInOurHost)
dwEffectMask |= CFM_DISABLED;
}
else
{
fCF = FALSE;
dwEffectMask = dwMaskApply & CFM_EFFECTS2;
}
// Reset effect bits to be modified and OR in supplied values
dwEffects &= ~dwEffectMask;
dwEffects |= pCF->dwEffects & dwEffectMask;
// wWeight is always used; so if a 1.0 CHARFORMAT tries to
// set BOLD/NOT BOLD, reset weight to be the appropriate value.
// Also, if CFM_BOLD is specified, it completely overrides
// any existing weight.
if(dwMaskApply & CFM_BOLD)
wWeight = (pCF->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
if(dwMaskApply & CFM_COLOR)
crTextColor = pCF->crTextColor;
if(dwMaskApply & ~CFM_EFFECTS) // Early out if only dwEffects
{ // is modified. Note that
if(dwMaskApply & CFM_SIZE) // CFM_EFFECTS includes CFM_COLOR
{
// If high word of input height is 0x8000, low word is signed
// increment in points
yHeight = HIWORD(pCF->yHeight) == 0x8000
? GetUsableFontHeight(yHeight, (SHORT)pCF->yHeight)
: pCF->yHeight;
}
if(dwMaskApply & CFM_OFFSET)
yOffset = pCF->yOffset;
if(dwMaskApply & CFM_CHARSET)
{
bCharSet = pCF->bCharSet;
if(!IsCharSetValid(bCharSet)) // Char set not valid, so set
{ // it to something sensible
bCharSet = DEFAULT_CHARSET;
}
}
if(dwMaskApply & CFM_FACE)
{
bPitchAndFamily = pCF->bPitchAndFamily;
wcscpy(szFaceName, pCF->szFaceName);
}
if( fCF ) // CHARFORMAT
dwEffects |= CFE_AUTOBACKCOLOR; // Be sure autobackcolor
else // CHARFORMAT2 extensions
{
if((dwMaskApply & (CFM_WEIGHT | CFM_BOLD)) == CFM_WEIGHT)
{
wWeight = pCF->wWeight;
// Set bold to be the appropriate value. The choice here
// comes from VB4.0 help. Basically, only high weight
// values are bold
dwEffects |= CFE_BOLD;
if(wWeight < 551)
dwEffects &= ~CFE_BOLD;
}
if(dwMaskApply & CFM_BACKCOLOR)
crBackColor = pCF->crBackColor;
if(dwMaskApply & CFM_LCID)
lcid = pCF->lcid;
if(dwMaskApply & CFM_SPACING)
sSpacing = pCF->sSpacing;
if(dwMaskApply & CFM_KERNING)
wKerning = pCF->wKerning;
if(dwMaskApply & CFM_STYLE)
sStyle = pCF->sStyle;
if(dwMaskApply & CFM_UNDERLINETYPE)
{
bUnderlineType = pCF->bUnderlineType;
if(!(dwMaskApply & CFM_UNDERLINE)) // If CFE_UNDERLINE
{ // isn't defined,
dwEffects &= ~CFE_UNDERLINE; // set it according to
if(bUnderlineType) // bUnderlineType
dwEffects |= CFE_UNDERLINE;
}
}
if((dwMaskApply & CFM_ANIMATION) && pCF->bAnimation <= 18)
bAnimation = pCF->bAnimation;
if(dwMaskApply & CFM_REVAUTHOR)
bRevAuthor = pCF->bRevAuthor;
}
}
SetCRC();
bInternalEffects &= ~pCF->bInternalMask;
bInternalEffects |= pCF->bInternalEffects & pCF->bInternalMask;
return NOERROR;
}
/*
* CCharFormat::ApplyDefaultStyle(pCF)
*
* @mfunc
* Set default style properties in this CCharFormat
*/
void CCharFormat::ApplyDefaultStyle (
LONG Style) //@parm Style to use
{
Assert(IsKnownStyle(Style));
if(IsHeadingStyle(Style))
{
LONG i = -Style + STYLE_HEADING_1;
LONG count = sizeof(g_Style) / sizeof(g_Style[0]);
if ((i >= count) || (i < 0))
return;
dwEffects = (dwEffects & 0xFFFFFF00) | g_Style[i].bEffects;
wWeight = (dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
if(g_Style[i].bHeight)
yHeight = g_Style[i].bHeight * 20;
//Bug 917
if(!bCharSet){
bCharSet = ANSI_CHARSET;
bPitchAndFamily = FF_SWISS;
wcscpy(szFaceName, L"Arial");
}
//
}
}
/*
* CCharFormat::Compare(pCF)
*
* @mfunc
* Compare this CCharFormat to *<p pCF>
*
* @rdesc
* TRUE if they are the same
*
* @devnote
* First compare 6 DWORDs of CCharFormat (dwEffects, yHeight, yOffset
* crTextColor, bCharSet, bPitchAndFamily, and first WORD of szFaceName).
* If they are identical, then compare the full szFaceName's. If they
* too are identical, compare the CHARFORMAT2 extensions. For
* CHARFORMAT, the extension values are taken to equal 0. Return
* TRUE only if all comparisons succeed. See also Delta(), which NINCH's
* the pCF->dwMask bits for parameters that differ between the two
* CCharFormats.
*
* *<p pCF> is an external CCharFormat, i.e., it's either a CHARFORMAT
* or a CHARFORMAT2 with the appropriate size given by cbSize. "This"
* CCharFormat is internal and cbSize is used as a reference count.
*/
BOOL CCharFormat::Compare (
const CCharFormat *pCF) const //@parm CCharFormat to compare this
{ // CCharFormat to
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::Compare");
BOOL fCF2 = pCF->cbSize == sizeof(CHARFORMAT2);
DWORD i;
DWORD * p1 = (DWORD *)this + 2; // Bypass cbSize & dwMask fields
DWORD * p2 = (DWORD *)pCF + 2;
for (i = 0; i < 6; i++) // Compare first six DWORDs
{ // (which includes most often
if(*p1++ != *p2++) // changed attributes, like
return FALSE; // dwEffects)
}
if(wcscmp(szFaceName, pCF->szFaceName)) // Compare font facename
return FALSE;
/* Compare CHARFORMAT2 extras:
* 1. (wWeight, sSpacing)
* 2. crBackColor
* 3. lcid
* 4. dwReserved
* 5. (wKerning, sStyle)
* 6. (bUnderlineType, bAnimation, bRevAuthor, bRes)
* 7. dwRes2 to add (msgtest needs to recompile)
*
* i.e., 7 DWORDs. Leave it 6 for now...
*/
#define NCF_EXTRAS 6
DWORD j;
p1 = (DWORD *)&this->wWeight;
p2 = (DWORD *)&pCF->wWeight;
AssertSz(offsetof(CCharFormat, wWeight) == 4*7 + sizeof(TCHAR)*LF_FACESIZE,
"CCharFormat::Compare: unpacked CCharFormat struct");
AssertSz(sizeof(CHARFORMAT2) == 4*(7 + NCF_EXTRAS) + sizeof(TCHAR)*LF_FACESIZE,
"CCharFormat::Compare: unexpected CCharFormat size");
AssertSz(dwReserved == 0,
"CCharFormat::Compare: nonzero dwReserved");
for (i = j = 0; i < NCF_EXTRAS; i++) // CHARFORMAT2 extensions
{
if(*p1++ != *p2++)
return FALSE;
}
return bInternalEffects == pCF->bInternalEffects;
}
/*
* CCharFormat::Delta(pCF)
*
* @mfunc
* Adjust pCF->dwMask for differences between this CCharformat and
* *<p pCF>
*
* @devnote
* *<p pCF> is an external CCharFormat, i.e., it's 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::Delta (
CCharFormat *pCF) const //@parm CCharFormat to compare this
{ // CCharFormat to
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CCharFormat::Delta");
// Collect bits for properties
LONG dwT = dwEffects ^ pCF->dwEffects; // that change. Note: auto
// color is handled since
if(yHeight != pCF->yHeight) // CFM_COLOR = CFE_AUTOCOLOR
dwT |= CFM_SIZE;
if(yOffset != pCF->yOffset)
dwT |= CFM_OFFSET;
if(crTextColor != pCF->crTextColor)
dwT |= CFM_COLOR;
if(bCharSet != pCF->bCharSet)
dwT |= CFM_CHARSET;
if((pCF->dwMask & CFM_FACE) && wcscmp(szFaceName, pCF->szFaceName))
dwT |= CFM_FACE;
if(pCF->cbSize > sizeof(CHARFORMAT))
{
if(crBackColor != pCF->crBackColor) // CHARFORMAT2 stuff
dwT |= CFM_BACKCOLOR;
if(wKerning != pCF->wKerning)
dwT |= CFM_KERNING;
if(lcid != pCF->lcid)
dwT |= CFM_LCID;
if(wWeight != pCF->wWeight)
dwT |= CFM_WEIGHT;
if(sSpacing != pCF->sSpacing)
dwT |= CFM_SPACING;
if(sStyle != pCF->sStyle)
dwT |= CFM_STYLE;
if(bUnderlineType != pCF->bUnderlineType)
dwT |= CFM_UNDERLINETYPE;
if(bAnimation != pCF->bAnimation)
dwT |= CFM_ANIMATION;
if(bRevAuthor != pCF->bRevAuthor)
dwT |= CFM_REVAUTHOR;
}
pCF->dwMask &= ~dwT; // Reset mask bits for
// properties that differ
// now handle internal properties
dwT = bInternalEffects ^ pCF->bInternalEffects;
pCF->bInternalMask &= ~dwT;
}
/*
* CCharFormat::fSetStyle(pCF)
*
* @mfunc
* return TRUE iff pCF specifies that the style should be set. See
* code for list of conditions for this to be true
*
* @rdesc
* TRUE iff pCF specifies that the style sStyle should be set
*/
BOOL CCharFormat::fSetStyle() const
{
return dwMask != CFM_ALL2 &&
dwMask & CFM_STYLE &&
cbSize == sizeof(CHARFORMAT2) &&
IsKnownStyle(sStyle);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -