📄 render.cpp
字号:
for(cchT = cch;
cchT > 0 && xWidth < _rcRender.right - _ptCur.x;
cchT--)
{
if (!_pccs->Include(*pch, tempwidth))
{
TRACEERRSZSC("CRenderer::TextOut(): Error filling CCcs", E_FAIL);
return TRUE;
}
// For DisplaySL
pch++;
xWidth += tempwidth;
}
// go back to start of chunk
pch -= (cch -= cchT);
}
else if(_fSelectToEOL)
{
// Add trailing whitespace at end of line (except extra EOP)
cchT = _cchWhite;
if(_cchEOP) // If EOP line, subtract cchEOP - 1
{ // _cchWhite - max(cchEOP - 1, 0)
cchT -= _cchEOP - 1;
// Because single line edit controls don't do a break at word, they
// don't keep track of white space so the count here can go
// negative or be 0. Because there is an EOP the count must be
// at least one (for the EOP), so we force it to 1.
if (cchT < 1)
cchT = 1;
}
tempwidth = 0; // Assume no whitespace to highlight
if (cchT) // There is whitespace...
{
// Use the width of the current font's space to highlight
if (!_pccs->Include(' ', tempwidth))
{
TRACEERRSZSC("CRenderer::TextOut(): Error no length of space",
E_FAIL);
return TRUE;
}
}
xWidthSelPastEOL = cchT * tempwidth + _pccs->_xOverhang;
xWidth = _xWidthLine + xWidthSelPastEOL - _xWidth;
_fSelectToEOL = FALSE; // Reset the flag
}
else
{
// last chunk and not selected, width of chunk is remaining
// width to end of line
xWidth = _xWidthLine - _xWidth;
}
_xWidth += xWidth;
SetClipLeftRight(xWidth);
if (_rc.right <= _rc.left)
{
// Entire text before display so we can exit here
_fSelected = FALSE;
goto Exit;
}
// Setup for drawing selections via ExtTextOut.
if(_fSelected || fIMEHighlight || _crBackground != _crCurBackground)
{
CheckEraseUptoMargin(xWidth, fIMEHighlight);
if(_fSelected)
{
CTxtSelection *psel = GetPed()->GetSelNC();
if (_pPF->InTable() && GetPrevChar() == CELL && psel &&
psel->fHasCell() && GetCp() == psel->GetCpMin())
{
_rc.left -= LXtoDX(_pPF->dxOffset);
}
// Set selection colors, saving old colors for restoration at end
crHighlight = GetPed()->TxGetSysColor(COLOR_HIGHLIGHT);
crHighlightText = GetPed()->TxGetSysColor(COLOR_HIGHLIGHTTEXT);
crPrevText = SetTextColor(_hdc, crHighlightText);
crPrevBack = SetBkColor (_hdc, crHighlight);
_crCurTextColor = crHighlightText;
}
fuOptions |= ETO_OPAQUE;
}
if (fuOptions == ETO_CLIPPED)
{
// Clipped is only set by itself if transparent render.
// Get top and bottom from _rc
rcClipTransparent = _rc;
// We just want to make sure that nothing extends beyond the
// view rectangle. Note that the view rectangle can start before
// the render rectangle due to a partial update in which case
// we clip to the render.
if (_rcRender.left <= _rcView.left)
{
rcClipTransparent.right = _rcView.right;
rcClipTransparent.left = _rcView.left;
}
else
{
rcClipTransparent.right = _rcRender.right;
rcClipTransparent.left = _rcRender.left;
}
prcForClip = &rcClipTransparent;
}
yOffsetForChar = _ptCur.y + _yHeight - _yDescent + _pccs->_yDescent
- _pccs->_yHeight - _pccs->_yOffset;
if( _fDisabled )
{
if( _crForeDisabled != _crShadowDisabled )
{
// the shadow should be offset by a hairline
// point; namely 3/4 of a point. Calculate
// how big this is in terms of the device units,
// but make sure it is at least 1 pixel.
DWORD offset;
// recall that a point is 1/72 of an inch
offset = MulDiv(3, _yMeasurePerInch, (4 * 72));
offset = max(offset, 1);
//draw the shadow
SetTextColor(_hdc, _crShadowDisabled);
W32->REExtTextOut(cm, _pccs->_wCodePage,
_hdc, _ptCur.x + offset,
yOffsetForChar + offset,
fuOptions, prcForClip, pch, cch, NULL, _fFEFontOnNonFEWin95);
// now set the drawing mode to transparent
bkModeOld = SetBkMode(_hdc, TRANSPARENT);
SetTextColor(_hdc, _crForeDisabled);
fuOptions &= ~ETO_OPAQUE;
}
else
SetTextColor(_hdc, _crForeDisabled);
}
W32->REExtTextOut(cm, _pccs->_wCodePage,
_hdc, _ptCur.x,
yOffsetForChar,
fuOptions, prcForClip, pch, cch, NULL, _fFEFontOnNonFEWin95);
// Restore background mode
if( _fDisabled && _crForeDisabled != _crShadowDisabled )
SetBkMode(_hdc, bkModeOld);
// Calculate width to draw for underline/strikeout
if(_bUnderlineType != CFU_UNDERLINENONE || _pccs->_fStrikeOut)
{
xWidthToDraw = xWidth - xWidthSelPastEOL;
xStart = _ptCur.x;
// Our host sets the clipping correctly so we don't need
// all the fancy calculations. However, other hosts don't so
// we need to clip underline and strikeout width by hand.
if ((fuOptions & ETO_CLIPPED) && !GetPed()->fInOurHost())
{
// Calculate maximum length of underline
xWidthClip = prcForClip->right - prcForClip->left;
// Is clipping width greater than view width?
if (xWidthClip > (_rcView.right - _rcView.left))
{
// Limit width to view width
xWidthClip = _rcView.right - _rcView.left;
}
// Is width to draw greater than clip width
if (xWidthClip < xWidthToDraw)
{
// Limit width to draw to clip width
xWidthToDraw = xWidthClip;
}
// Is the starting point of the underline in the view area?
if (_rcView.left > xStart)
{
// Remove the unshown part on the left from the width to draw
xWidthToDraw -= (_rcView.left > xStart);
// Put the starting point of the rectangle in the client area
xStart = _rcView.left;
}
// Does width fall out side the view rectange to the right?
if (xStart + xWidthToDraw > _rcView.right)
{
// Yes - limit to the view rectangle on the right
xWidthToDraw = _rcView.right - xStart;
}
}
// BUGBUG (AndreiB) xWidthToDraw may be negative at this point
// because of a bug in the previous code: _xWidthLine comes
// from CLine and does NOT include trailing white space
// whereas _xWidth is just a sum of widths of rendered chuncks and DOES
// include trailing white space.
// To patch this situation is the safest possible manner we just
// catch this case here:
if (xWidthToDraw > 0)
{
// Is there an underline required?
if ( _bUnderlineType != CFU_UNDERLINENONE)
{
// Yes - do it.
RenderUnderline(xStart, xWidthToDraw);
}
// Is there a strikeout required?
if (_pccs->_fStrikeOut)
{
RenderStrikeOut(xStart, xWidthToDraw);
}
}
}
if(_fSelected )
{
SetTextColor(_hdc, crPrevText);
SetBkColor(_hdc, crPrevBack);
_crCurTextColor = crPrevText;
_fSelected = FALSE;
}
Exit:
// Update current point
_ptCur.x = _rc.right;
return cch;
}
/*
* CRenderer::CheckEraseUptoMargin (xWidth, fIMEHighlight)
*
* @mfunc
* Erase up to left margin if background color for starting character
* differs from default background color. This happens if the
* starting character is selected or highlighted for IME (IME should be
* done as the next case), or if _crCurBackground differs from the
* default background color (_crBackground).
*/
void CRenderer::CheckEraseUptoMargin(
LONG xWidth, //@parm Width of text to be displayed
BOOL fIMEHighlight) //@parm IME flag that should go away...
{
if (_fRecalcRectForInvert) // SetClipLeftRight() may set
{ // this if(_fFirstChunk)
RECT rc = _rc; // Save current rect in case
LONG x = _ptCur.x; // _rc.left is changed
CTxtSelection *psel = GetPed()->GetSelNC();
if(_pPF->InTable() && _fSelected && psel && psel->fHasCell())
x -= LXtoDX(_pPF->dxOffset);
if(x > _rcView.left)
{
_rc.left = max(x, _rc.left);
// If we aren't really going to display a selection
// and there is actually something to display move the
// left margin back.
if (_rc.left == _rc.right && xWidth)
_rc.left -= xWidth;
}
if (_rc.left > rc.left) // Something to erase
{
rc.right = _rc.left;
// Erase up to left margin
if (fIMEHighlight || _crBackground != _crCurBackground)
{
// Setup background color for EraseTextOut
COLORREF cr = SetBkColor(_hdc, _crBackground);
EraseTextOut(_hdc, &rc);
SetBkColor(_hdc, cr); // Restore background color
}
else
EraseTextOut(_hdc, &rc);
}
_fRecalcRectForInvert = FALSE;
}
}
/*
* CRenderer::RenderTabs (cchMax)
*
* @mfunc
* Render a span of zero or more tab characters in chunk *this
*
* @rdesc
* number of tabs rendered
*
* @devnote
* *this is advanced by number of tabs rendered
* MS - tabs should be rendered using opaquing rect of adjacent string
*/
LONG CRenderer::RenderTabs(
LONG cchMax) //@parm Max cch to render (cch in chunk)
{
TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::RenderTabs");
LONG cch = cchMax;
LONG ch = GetChar();
LONG chPrev = 0;
LONG xTab, xTabs;
for(xTabs = 0; cch && (ch == TAB || ch == CELL); cch--)
{
xTab = MeasureTab(ch);
_xWidth += xTab; // Advance internal width
xTabs += xTab; // Accumulate width of tabbed
Advance(1); // region
chPrev = ch;
ch = GetChar();
}
if (_xWidth > _xWidthLine)
{
xTabs = 0;
_xWidth = _xWidthLine;
}
if(xTabs)
{
LONG dx = 0;
LONG xGap = 0;
if(_fSelected && chPrev == CELL && ch != CR)
{
LONG cpSelMin, cpSelMost;
GetPed()->GetSelRangeForRender(&cpSelMin, &cpSelMost);
if(GetCp() == cpSelMin || GetCp() == cpSelMost)
{
xGap = LXtoDX(_pPF->dxOffset);
if(GetCp() == cpSelMost)
{
dx = xGap;
xGap = 0;
}
}
}
SetClipLeftRight(xTabs - dx);
if(_rc.left < _rc.right) // Something to erase
{
if (_fSelected) // Use selection background color
{
CheckEraseUptoMargin(xTabs - dx, FALSE);
_rc.left -= xGap;
SetBkColor(_hdc, GetPed()->TxGetSysColor(COLOR_HIGHLIGHT));
}
// Paint background with appropriate color
if (_fErase || _fSelected || _crBackground != _crCurBackground)
EraseTextOut(_hdc, &_rc);
if (_fSelected) // Restore background color
SetBkColor(_hdc, _crCurBackground);
}
// Update current point
_ptCur.x += xTabs;
}
return cchMax - cch; // Return # tabs rendered
}
/*
* CRenderer::SetNewFont ()
*
* @mfunc
* Select appropriate font and color in the _hdc based on the
* current character format. Also sets the background color
* and mode.
*
* @rdesc
* TRUE if it succeeds
*/
BOOL CRenderer::SetNewFont()
{
TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::SetNewFont");
const CCharFormat *pcf = GetCF();
CTxtEdit *ped = GetPed();
if ( (NULL == pcf) || (NULL == ped))
{
TRACEWARNSZ("NULL pointer in CRenderer::SetNewFont");
return FALSE;
}
// get information about disabled
_fDisabled = FALSE;
if( (pcf->dwEffects & CFE_AUTOCOLOR) &&
(pcf->dwEffects & CFE_DISABLED) )
{
_fDisabled = TRUE;
_crForeDisabled = ped->TxGetSysColor(COLOR_3DSHADOW);
_crShadowDisabled = ped->TxGetSysColor(COLOR_3DHILIGHT);
if( _crForeDisabled == CLR_INVALID ||
_crShadowDisabled == CLR_INVALID )
{
_crForeDisabled = _crShadowDisabled =
ped->TxGetSysColor(COLOR_GRAYTEXT);
}
}
// Save the old font
CCcs *pccsOld = _pccs;
// Retrieves new font to use
Assert(_hdcMeasure);
_pccs = fc().GetCcs(_hdcMeasure, pcf, _pdp->GetZoomNumerator(),
_pdp->GetZoomDenominator(), _yMeasurePerInch);
if(!_pccs)
{
TRACEERRSZSC("CRenderer::SetNewFont(): no CCcs", E_FAIL);
return FALSE;
}
// Select font in _hdc
AssertSz(_pccs->_hfont, "CRenderer::SetNewFont _pccs->_hfont is NULL");
SetFontAndColor(pcf);
// Release previous font in use. We may do so safely now because the new font is now in play.
if(pccsOld)
{
pccsOld->Release();
}
// Assume no underlineing
_bUnderlineType = CFU_UNDERLINENONE;
// We want to draw revision marks with underlining, so
// just fake out our font information.
if( (pcf->dwEffects & CFE_UNDERLINE) || (pcf->dwEffects & CFE_REVISED) )
{
// We only do single underline except in a few special cases.
_bUnderlineType = CFU_UNDERLINE;
if (pcf->bUnderlineType >= CFU_UNDERLINEDOTTED)
{
// The special cases that we do the special underlines
_bUnderlineType = pcf->bUnderlineType;
}
}
return TRUE;
}
/*
* CRenderer::SetFontAndColor (pcf)
*
* @mfunc
* Select appropriate font and color in the _hdc based on the
* current character format. Also sets the background color
* and mode.
*
* @rdesc
* None.
*/
void CRenderer::SetFontAndColor(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -