📄 frunptr.cpp
字号:
if(iFormat == GetRun(0)->_iFormat)
{ // Like formatted runs
if(iDirection > 0) // Point at the first of the
PrevRun(); // two runs
cch = GetRun(0)->_cch; // Save its count
Remove(1, AF_KEEPMEM); // Remove it
pf->ReleaseFormat(iFormat); // Decrement its reference count
GetRun(0)->_cch += cch; // Add its count to the other's,
} // i.e., they're merged
}
}
/*
* CFormatRunPtr::SetFormat(ifmt, cch, pf)
*
* @mfunc
* Set format for up to cch chars of this run to ifmt, splitting run
* as needed, and returning the character count actually processed
*
* @rdesc
* character count of run chunk processed, INFINITE on failure
* this points at next run
*
* Comments:
* Changes this run ptr. cch must be >= 0.
*
* Note 1) for the first run in a series, _ich may not = 0, and 2) cch
* may be <lt>, =, or <gt> the count remaining in the run. The algorithm
* doesn't split runs when the format doesn't change.
*/
DWORD CFormatRunPtr::SetFormat(
LONG ifmt, //@parm format index to use
DWORD cch, //@parm character count of remaining format range
IFormatCache * pf) //@parm pointer to IFormatCache to
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CFormatRunPtr::SetFormat");
// AddRefFormat/ReleaseFormat
DWORD cchChunk;
LONG iFormat;
CFormatRun * pRun;
_TEST_INVARIANT_
if(!IsValid())
return 0;
pRun = GetRun(0); // pRun points at current run in
cchChunk = pRun->_cch - _ich; // this function
iFormat = pRun->_iFormat;
AssertSz(cch, "Have to have characters to format!");
AssertSz(pRun->_cch, "uh-oh, empty format run detected");
if(ifmt != iFormat) // New and current formats differ
{
AssertSz(cchChunk, "Caller did not call AdjustForward");
if(_ich) // Not at either end of run: need
{ // to split into two runs of
if(!(pRun = Insert(1))) // counts _ich and _pRun->_cch
{ // - _ich, respectively
return INFINITE; // Out of RAM: do nothing; just
} // keep current format
pRun->_cch = _ich;
pRun->_iFormat = iFormat; // New run has same format
pf->AddRefFormat(iFormat); // Increment format ref count
NextRun(); // Go to second (original) run
IncPtr(pRun); // Point pRun at current run
pRun->_cch = cchChunk; // Note: IncPtr is a bit more
} // efficient than GetRun, but
// trickier to code right
if(cch < cchChunk) // cch doesn't cover whole run:
{ // need to split into two runs
if(!(pRun = Insert(1)))
{
// Out of RAM, so formatting's wrong, oh well. We actually
// "processed" all of the characters, so return that (though
// the tail end formatting isn't split out right)
return cch;
}
pRun->_cch = cch; // New run gets the cch
pRun->_iFormat = ifmt; // and the new format
IncPtr(pRun); // Point pRun at current run
pRun->_cch = cchChunk - cch; // Set leftover count
}
else // cch as big or bigger than
{ // current run
pf->ReleaseFormat(iFormat); // Free run's current format
pRun->_iFormat = ifmt; // Change it to new format
} // May get merged later
pf->AddRefFormat(ifmt); // Increment new format ref count
}
else if( cchChunk == 0 )
{
pRun->_cch += cch;
cchChunk = cch;
}
cch = min(cch, cchChunk);
AdvanceCp(cch);
AdjustForward();
return cch;
}
/*
* CFormatRunPtr::GetFormat()
*
* @mfunc
* return format index at current run pointer position
*
* @rdesc
* current format index
*/
LONG CFormatRunPtr::GetFormat() const
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CFormatRunPtr::GetFormat");
_TEST_INVARIANT_
return IsValid() ? GetRun(0)->_iFormat : -1;
}
/*
* CFormatRunPtr::AdjustFormatting(cch, pf)
*
* @mfunc
* Use the same format index for the cch chars at this run ptr
* as that immediately preceeding it (if on run edge).
*
* @devnote
* This runptr ends up pointing at what was the preceeding run,
* since the current run has been moved into the preceeding run.
*
* FUTURE: might be better to take the cch equal to chars in
* the following run.
*/
void CFormatRunPtr::AdjustFormatting(
DWORD cch, //@parm Count of chars to extend formatting
IFormatCache *pf) //@parm Format cache ptr for AddRef/Release
{
if(!IsValid())
return; // Nothing to merge
CFormatRunPtr rp(*this);
// Move this run ptr to end of
AdjustBackward(); // preceeding run (if at run edge)
rp.AdjustForward(); // (merge may delete run at entry)
if(_iRun != rp._iRun) // On a format edge: copy previous
{ // format index over
rp.SetFormat(GetFormat(), cch, pf); // Format cch chars at this
rp.MergeRuns(_iRun, pf); // runptr
}
}
///////////////////////////// CCFRunPtr ///////////////////////////////
CCFRunPtr::CCFRunPtr(const CRchTxtPtr &rtp)
: CFormatRunPtr(rtp._rpCF)
{
_ped = rtp.GetPed();
}
/*
* CCFRunPtr::IsHidden()
*
* @mfunc
* return TRUE if CCharFormat for this run ptr has CFE_HIDDEN bit set
*
* @rdesc
* TRUE if CCharFormat for this run ptr has CFE_HIDDEN bit set
*/
BOOL CCFRunPtr::IsHidden()
{
return (_ped->GetCharFormat(GetFormat())->dwEffects & CFE_HIDDEN) != 0;
}
/*
* CCFRunPtr::IsInHidden()
*
* @mfunc
* return TRUE if CCharFormat for this run ptr has CFE_HIDDEN bit set
*
* @rdesc
* TRUE if CCharFormat for this run ptr has CFE_HIDDEN bit set
*/
BOOL CCFRunPtr::IsInHidden()
{
AdjustForward();
BOOL fHidden = IsHidden();
if(_ich)
return fHidden;
AdjustBackward();
return fHidden && IsHidden();
}
/*
* CCFRunPtr::FindUnhidden()
*
* @mfunc
* Find nearest expanded CF going forward. If none, find nearest going
* backward. If none, go to start of document
*
* @rdesc
* cch to nearest expanded CF as explained in function description
*
* @devnote
* changes this run ptr
*/
LONG CCFRunPtr::FindUnhidden()
{
LONG cch = FindUnhiddenForward();
if(IsHidden())
cch = FindUnhiddenBackward();
return cch;
}
/*
* CCFRunPtr::FindUnhiddenForward()
*
* @mfunc
* Find nearest expanded CF going forward. If none, go to EOD
*
* @rdesc
* cch to nearest expanded CF going forward
*
* @devnote
* changes this run ptr
*/
LONG CCFRunPtr::FindUnhiddenForward()
{
LONG cch = 0;
AdjustForward();
while(IsHidden())
{
cch += GetCchLeft();
if(!NextRun())
break;
}
return cch;
}
/*
* CCFRunPtr::FindUnhiddenBackward()
*
* @mfunc
* Find nearest expanded CF going backward. If none, go to BOD
*
* @rdesc
* cch to nearest expanded CF going backward
*
* @devnote
* changes this run ptr
*/
LONG CCFRunPtr::FindUnhiddenBackward()
{
LONG cch = 0;
AdjustBackward();
while(IsHidden())
{
cch -= GetIch();
if(!_iRun)
break;
_ich = 0;
AdjustBackward();
}
return cch;
}
///////////////////////////// CPFRunPtr ///////////////////////////////
CPFRunPtr::CPFRunPtr(const CRchTxtPtr &rtp)
: CFormatRunPtr(rtp._rpPF)
{
_ped = rtp.GetPed();
}
/*
* CPFRunPtr::FindHeading(cch, lHeading)
*
* @mfunc
* Find heading with number lHeading (e.g., = 1 for Heading 1) or above
* in a range starting at this PFrun pointer. If successful, this run
* ptr points at the matching run; else it remains unchanged.
*
* @rdesc
* cch to matching heading or tomBackward if not found
*
* @devnote
* changes this run ptr
*/
LONG CPFRunPtr::FindHeading(
LONG cch, //@parm Max cch to move
LONG& lHeading) //@parm Lowest lHeading to match
{
LONG cchSave = cch;
DWORD ichSave = _ich;
DWORD iRunSave = _iRun;
LONG OutlineLevel;
Assert((unsigned)lHeading <= NHSTYLES);
if(!IsValid())
return tomBackward;
while(TRUE)
{
OutlineLevel = GetOutlineLevel();
if (!(OutlineLevel & 1) &&
(!lHeading || (lHeading - 1)*2 >= OutlineLevel))
{
lHeading = OutlineLevel/2 + 1; // Return heading # found
return cchSave - cch; // Return how far away it was
}
if(cch >= 0)
{
cch -= GetCchLeft();
if(cch <= 0 || !NextRun())
break;
}
else
{
cch += GetIch();
if(cch > 0 || !_iRun)
break;
AdjustBackward();
}
}
_ich = ichSave;
_iRun = iRunSave;
return tomBackward; // Didn't find desired heading
}
/*
* CPFRunPtr::IsCollapsed()
*
* @mfunc
* return TRUE if CParaFormat for this run ptr has PFE_COLLAPSED bit set
*
* @rdesc
* TRUE if CParaFormat for this run ptr has PFE_COLLAPSED bit set
*/
BOOL CPFRunPtr::IsCollapsed()
{
return (_ped->GetParaFormat(GetFormat())->wEffects & PFE_COLLAPSED) != 0;
}
/*
* CPFRunPtr::FindExpanded()
*
* @mfunc
* Find nearest expanded PF going forward. If none, find nearest going
* backward. If none, go to start of document
*
* @rdesc
* cch to nearest expanded PF as explained in function description
*
* @devnote
* changes this run ptr
*/
#ifdef PWD_JUPITER // GuyBark Jupiter 18391:
LONG CPFRunPtr::FindExpanded(BOOL bDisallowBackwardSearch)
#else
LONG CPFRunPtr::FindExpanded()
#endif // PWD_JUPITER
{
LONG cch, cchRun;
for(cch = 0; IsCollapsed(); cch += cchRun) // Try to find expanded PF
{ // run going forward
cchRun = GetCchLeft();
if(!NextRun()) // Aren't any
{
#ifdef PWD_JUPITER
// GuyBark Jupiter 18391:
// Say the last header in the document has some collapsed text
// beneath it. If the user moves the last heading up, we end up
// here trying to find the first not-collapsed text after the
// heading. To be here, we know all the text beneath the heading
// up to the end of the document is collapsed. Previously the code
// would say, ok, let's work backwards instead. But we don't want
// to do that. We should account for all the collapsed text up to
// the end of the document, so we can move all that text around
// with the heading.
// Note: FindExpanded() is also called to find the limits of the
// collapsed range if the selection becomes part of a collapsed
// range. Eg, the user's just entered Outline View, and the selection
// is no longer visible. Call the old code in that case.
if(bDisallowBackwardSearch)
{
cch += cchRun;
break;
}
#endif // PWD_JUPITER
AdvanceCp(-cch); // Go back to starting point
return FindExpandedBackward(); // Try to find expanded PF
} // run going backward
}
return cch;
}
/*
* CPFRunPtr::FindExpandedForward()
*
* @mfunc
* Find nearest expanded PF going forward. If none, go to EOD
*
* @rdesc
* cch to nearest expanded PF going forward
*
* @devnote
* changes this run ptr
*/
LONG CPFRunPtr::FindExpandedForward()
{
LONG cch = 0;
while(IsCollapsed())
{
LONG cchLeft = GetCchLeft();
_ich += cchLeft; // Update _ich in case
cch += cchLeft; // !NextRun()
if(!NextRun())
break;
}
return cch;
}
/*
* CPFRunPtr::FindExpandedBackward()
*
* @mfunc
* Find nearest expanded PF going backward. If none, go to BOD
*
* @rdesc
* cch to nearest expanded PF going backward
*
* @devnote
* changes this run ptr
*/
LONG CPFRunPtr::FindExpandedBackward()
{
LONG cch = 0;
while(IsCollapsed())
{
cch -= GetIch();
_ich = 0;
if(!_iRun)
break;
AdjustBackward();
}
return cch;
}
/*
* CPFRunPtr::GetOutlineLevel()
*
* @mfunc
* Find outline level this rp is pointing at
*
* @rdesc
* Outline level this rp is pointing at
*/
LONG CPFRunPtr::GetOutlineLevel()
{
const CParaFormat *pPF = _ped->GetParaFormat(GetFormat());
if (NULL == pPF)
{
Assert(pPF);
return 0;
}
LONG OutlineLevel = pPF->bOutlineLevel;
AssertSz(IsHeadingStyle(pPF->sStyle) ^ (OutlineLevel & 1),
"CPFRunPtr::GetOutlineLevel: sStyle/bOutlineLevel mismatch");
return OutlineLevel;
}
/*
* CPFRunPtr::GetStyle()
*
* @mfunc
* Find style this rp is pointing at
*
* @rdesc
* Style this rp is pointing at
*/
LONG CPFRunPtr::GetStyle()
{
const CParaFormat *pPF = _ped->GetParaFormat(GetFormat());
if (NULL == pPF)
{
Assert(pPF);
return 0;
}
LONG Style = pPF->sStyle;
AssertSz(IsHeadingStyle(Style) ^ (pPF->bOutlineLevel & 1),
"CPFRunPtr::GetStyle: sStyle/bOutlineLevel mismatch");
return Style;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -