⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// Set the background color to the default for clearing the bitmap
	// We need to do this everytime since the bitmap dc may contain
	// a different background color carried on from last line even thought
	// _crBackground == _crCurBackground.
	SetBkColor(_hdc, _crBackground);

#ifdef PWD_JUPITER
	// GuyBark Jupiter 35187:
	// Make sure the offscreen dc gets the same text color as the render dc.
	// This allows outline symbols to be drawn in the correct color. The 
	// outline sybols are contained in monochrome bitmaps in the resource file.
	SetTextColor(_hdc, colText);
#endif // PWD_JUPITER

	// Clear the bit map
	_osdc.FillBitmap(_rcRender.right - _rcRender.left, yHeightOfBitmap);

	// Restore the background color if necessary
	if (_crBackground != _crCurBackground)
	{
		SetBkColor(_hdc, _crCurBackground);
	}

	// Store the value to normalize the y offset for rendering
	// to the off screen bitmap
	yAdj = _rc.top;

	// Normalize _rc and _ptCur height for rendering to the off 
	// screen bitmap.
	_ptCur.y -= yAdj;
	_rc.top = 0;
	_rc.bottom -= yAdj;

	// Store value to normalize the x offset for rendering
	xAdj = _rcRender.left;

	// Adjust the _rcRender & _rcView so they are relative to x of 0.
	_rcRender.left = 0;
	_rcRender.right -= xAdj;
	_rcView.left -= xAdj;
	_rcView.right -= xAdj;
	_ptCur.x -= xAdj;

	yRcIgnored = 0;
	LONG yRcIgnoredTemp = yHeightRC - yHeightOfBitmap;

	if (yRcIgnoredTemp > 0)
	{
		yRcIgnored = yRcIgnoredTemp;
		_rc.bottom -= yRcIgnoredTemp;
	}

	return hdcSave;
}

/*
 *	CRenderer::RenderOffScreenBitmap(osdc, hdc, xAdj, yAdj, yRcIgnored)
 *
 *	@mfunc
 *		Render off screen bit map and restore the state of the render.
 *
 *	@devnote
 *		This is inline because it is only called in one place. If for some
 *		reason this becomes generally useful, please remove the inline.
 */
INLINE void CRenderer::RenderOffScreenBitmap(
	COffScreenDC& osdc,	//@parm off screen DC object
	HDC hdc,			//@parm DC to render to
	LONG xAdj,			//@parm offset to real x base
	LONG yAdj,			//@parm offset to real y base 
	LONG yRcIgnored)	//@parm part of display rectangle that not processed
{	
	// Palettes for rendering bit map
	HPALETTE hpalOld = NULL;
	HPALETTE hpalNew = NULL;

	// For clearing extra area in screen
	RECT rcErase;

	// Temp place for height of RC used in min calc below
	LONG yHeightOfBitmap = CalcHeightBitmap(_rc.bottom - _rc.top);

	// Restore the y offset
	_ptCur.y += yAdj;
	_rc.top += yAdj;
	_rc.bottom += yAdj;

	// Restore x offset
	_rcRender.left += xAdj;
	_rcRender.right += xAdj;
	_rcView.left += xAdj;
	_rcView.right += xAdj;
	_ptCur.x += xAdj;

	// Create a palette if one is needed
	if (_plogpalette != NULL)				
	{
		W32->ManagePalette(hdc, _plogpalette, hpalOld, hpalNew);
	}

	// Render the bit map to the real DC and restore _ptCur & _rc
	_osdc.RenderBitMap(hdc, xAdj, yAdj, 
		_rcRender.right - _rcRender.left, yHeightOfBitmap);

	// Restore palette after render if necessary
	if (_plogpalette != NULL)				
	{
		W32->ManagePalette(hdc, _plogpalette, hpalOld, hpalNew);
		delete _plogpalette;
		_plogpalette = NULL;
	}

	// Restore the HDC to the actual render DC
	_hdc = hdc;

	// Set this flag to what it should be for the restored DC
	_fErase = TRUE;

	// Is there display space that needs to be cleared?
	if (yRcIgnored)
	{
		// Clear screen area that was ignored in the off screen DC
		rcErase.top = _rc.bottom;
		rcErase.bottom = _rc.bottom + yRcIgnored;
		rcErase.left = _rcRender.left;
		rcErase.right = _rcRender.right;
		EraseTextOut(_hdc, &rcErase);

		// Restore RC to its original state
		_rc.bottom += yRcIgnored;
	}

	// Reset the screen DC font 

	// Set up the font on the non-screen DC
	if (!FormatIsChanged())
	{
		// We are not on a new block so just set the font and color
		SetFontAndColor(GetCF());
	}
	else
	{
		// We are on a new block so reset everything.
		ResetCachediFormat();
		SetNewFont();
	}
}

/*
 *	CRenderer::RenderLine (&li, fLastLine)
 *
 *	@mfunc
 *		Render visible part of current line
 *
 *	@rdesc
 *		TRUE if should be called for next line
 *		FALSE if error or bottom of rendering rectangle reached
 */
BOOL CRenderer::RenderLine (
	CLine &	li,
	BOOL	fLastLine)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::RenderLine");

	LONG 	cchChunk;
	LONG	cchInTextRun;
	LONG 	cch;
	LONG	cpSelMin;
	LONG	cpSelMost;
	LONG	cpIMEInvertMin;
	LONG	cpIMEInvertMost;
	BOOL 	fSelectionInLine;
	BOOL	fIMEHighlight = FALSE;
	const WCHAR *pstrToRender;
	BOOL	fAccelerator = FALSE;
	HDC		hdcSave = NULL;
	LONG	yAdj;
	LONG	xAdj;
	LONG	yRcIgnored;
	WCHAR	wcPasswordChar = GetPasswordChar();
	CTempWcharBuf twcb;
	BYTE	bUnderlineSave = 0;

	// This is used as a temporary buffer so that we can guarantee that we will
	// display an entire format run in one ExtTextOut.
	WCHAR *	pszTempBuffer = NULL;

	_pPF = GetPF();						// Be sure our CParaFormat ptr is OK

	// Get the range that we should display for this rendering.
	GetPed()->GetSelRangeForRender(&cpSelMin, &cpSelMost);

	// Set flag indicating rendering last line of the display
	_fLastLine = fLastLine;

	// Init render at start of line
	NewLine(li);

	if(_fCollapsed)						// Line is collapsed in Outline mode
	{
		Advance(_cch);					// Bypass line
		return TRUE;					// Let dispml continue with next line
	}

	// Set flag indicating whether part of the line is selected
	fSelectionInLine = (cpSelMost != cpSelMin) 
		&& (GetCp() < cpSelMost) && (GetCp() + (LONG)_cch > cpSelMin);

	// Check IME to see if it needs to set text color or background
	if ( !fSelectionInLine
		&& IMECheckGetInvertRange(GetPed(), cpIMEInvertMin, cpIMEInvertMost))
	{
		fIMEHighlight = fSelectionInLine = (cpIMEInvertMost != cpIMEInvertMin) 
			&& (GetCp() < cpIMEInvertMost)
				&& (GetCp() + (LONG)_cch > cpIMEInvertMin);
	}

	
	// Compute top of clipping rect
	// a priori = top of rendering rect
	_rc.top = _rcRender.top;

	// limit to top of view rect if selection in line or line starts
	// above that point
	if(_rc.top < _rcView.top 
		&& (fSelectionInLine || (_ptCur.y < _rcView.top)
			|| (_bFlags & fliUseOffScreenDC)))
	{
		_rc.top = _rcView.top;
		_fClipTopToView = TRUE;
	}

	// limit to top of line if it's below the top of view 
	if(_ptCur.y > _rcView.top)
		_rc.top = max(_rc.top, _ptCur.y);

	// Compute bottom of clipping rect
	// a priori = bottom of the rendering rect
	_rc.bottom = _rcRender.bottom;

	// limit to bottom of view rect if selection in line or line extends
	// below that point
	if(_rc.bottom > _rcView.bottom &&
		(fSelectionInLine || (_ptCur.y + _yHeight > _rcView.bottom)
			|| (_bFlags & fliUseOffScreenDC)))
	{
		_rc.bottom = _rcView.bottom;
		_fClipBottomToView = TRUE;
	}
	// limit to bottom of line if not last line or selection in line
	//if(!_fLastLine || fSelectionInLine)
	{
		_rc.bottom = min(_ptCur.y + _yHeight, _rc.bottom);
	}

	// We use an off screen DC if there are characters to render and the
	// measurer determined that this line needs off screen rendering. The
	// main reason for the measurer deciding that a line needs off screen
	// rendering is if there are multiple formats in the line.
	if (_cch > 0 && _fUseOffScreenDC && (_bFlags & fliUseOffScreenDC))
	{
		// Set up an off screen if we can. Note that if this fails,
		// we just use the regular DC which won't look as nice but
		// will at least display something readable.
		hdcSave = SetUpOffScreenDC(_osdc, xAdj, yAdj, yRcIgnored);

		// Is this a uniform text being rendered off screen?
		if ((li._bFlags & fliOffScreenOnce) != 0)
		{
			// Yes - turn off the special rendering since the line
			// has been rendered.
			li._bFlags &= ~(fliOffScreenOnce | fliUseOffScreenDC);
		}
	}

	// Allow for special rendering at start of line
	LONG x = _ptCur.x;
	if( !RenderStartLine() )
	{
		AssertSz(FALSE,"render start failed");
	}

	Assert(GetCp() + _cch <= (DWORD)GetTextLength());

	cch = _cch;

	if ((wcPasswordChar != 0) && IsRich())
	{
		// It is kind of bad to allow rich text password edit controls.
		// However, it does make it that much easier to create a password
		// edit control since you don't have to know to change the box to
		// plain. Anyway, if there is such a thing, we don't want to put
		// out password characters for EOPs in general and the final EOP
		// specifically. Therefore, the following ...
		if (GetPed()->TxGetMultiLine())
		{
			cch -= _cchEOP;
		}
		else
		{
			cch = GetPed()->GetAdjustedTextLength();
		}
	}

	for(; cch > 0; cch -= cchChunk)
	{
		// Initial chunk (number of character to render in a single TextOut)
		// is min between CHARFORMAT run length and line length.

		pstrToRender = NULL;

		// Set chunk count to number of characters left in current format run
		cchChunk = GetCchLeftRunCF();
		AssertSz(cchChunk != 0, "empty CHARFORMAT run");

		if(GetCF()->dwEffects & CFE_HIDDEN)			// Don't display hidden
		{											//  text
			Advance(cchChunk);
			continue;
		}

		// Limit chunk to number of characters we want to display.
		cchChunk = min(cch, cchChunk);

		// Get the number of characters in the text run
		pstrToRender = _rpTX.GetPch(cchInTextRun);
		AssertSz(cchInTextRun > 0, "empty text run");

		if ((cchInTextRun < cchChunk) || (wcPasswordChar != 0))
		{
			// The amount of data in the backing store run is less than the
			// number of characters we wish to display. We will copy the
			// data out of the backing store.

			// Allocate a buffer if it is needed
			if (NULL == pszTempBuffer)
			{
				// Allocate a buffer big enough to handle all future
				// requests in this loop.
				pszTempBuffer = twcb.GetBuf(cch);
			}

			// Make the string to render point to the buffer
			pstrToRender = pszTempBuffer;

			if (0 == wcPasswordChar)
			{
				// Password not requested so copy the data to the buffer
				// from the backing store.
				_rpTX.GetText(cchChunk, pszTempBuffer);
			}
			else
			{
				// Fill the buffer with password characters
				for (int i = 0; i < cchChunk; i++)
				{
					pszTempBuffer[i] = wcPasswordChar;
				}
			}
		}

		if (_cpAccelerator != -1)
		{
			// Get the current cp
			LONG cpCur = GetCp();

			// Does the accelerator character fall in this chunk?
			if (cpCur < _cpAccelerator && (cpCur + cchChunk) > _cpAccelerator)
			{
				// Reduce the chunk to the character just before the accelerator
				cchChunk = _cpAccelerator - cpCur;
			}
			// Is this character the accelerator?
			else if (cpCur == _cpAccelerator)
			{
				// Set chunk size to 1 since we only want to output
				// the character with the underline.
				cchChunk = 1;

				// Tell down stream routines that we are handling accelerator
				fAccelerator = TRUE;

				// We don't need to bother with the accelerator because 
				// it will be processed now.
				_cpAccelerator = -1;
			}
		}
		
		// Reduce chunk to account for selection if we are rendering for a
		// display that cares about selections.
		if(_fRenderSelection && cpSelMin != cpSelMost)
		{
			LONG cchSel = cpSelMin - GetCp();
			if(cchSel > 0)
				cchChunk = min(cchChunk, cchSel);

			else if(GetCp() < cpSelMost)
			{
				cchSel = cpSelMost - GetCp();
				if (cchSel >= cch)
					_fSelectToEOL = TRUE;

				else
					cchChunk = min(cchChunk, cchSel);

				_fSelected = TRUE;
			}
		}

		// if start of CHARFORMAT run, select font and color
		if (!_pccs || FormatIsChanged())
		{
			ResetCachediFormat();
			if (!SetNewFont())
				return FALSE;
		}

		if (fAccelerator)
		{
			bUnderlineSave = _bUnderlineType;
			_bUnderlineType = CFU_UNDERLINE;
		}

		// Allow for further reduction of the chunk and rendering of 
		// interleaved rich text elements

		if(RenderChunk(cchChunk, pstrToRender, cch))
		{
			AssertSz(cchChunk > 0, "CRenderer::RenderLine(): cchChunk == 0");
			_fSelected = FALSE;
			continue;
		}

		AssertSz(cchChunk > 0, "CRenderer::RenderLine() - cchChunk == 0");

		// Figure if last chunk of the line
		_fLastChunk = (cchChunk == cch);

		// now render the text
		TextOut(pstrToRender, cchChunk, fIMEHighlight);
		fIMEHighlight = FALSE;

		if (fAccelerator)
		{
			_bUnderlineType = bUnderlineSave;

			// Turn off the special accelerator processing
			fAccelerator = FALSE;
		}

		Advance(cchChunk);

		// break if we went past the right of the render rect.
		if (_ptCur.x >= min(_rcView.right, _rcRender.right))
		{
			cch -= cchChunk;
			break;
		}
	}

extern const COLORREF g_Colors[];

	if(_pPF->InTable())
	{
		LONG h = LXtoDX(_pPF->dxOffset);
		x -= h;
		LONG dx = LXtoDX(_pPF->dxStartIndent);
		LONG xRight = x	+ LXtoDX(GetTabPos(_pPF->rgxTabs[_pPF->cTabCount - 1])) - dx;
		HPEN pen = CreatePen(PS_SOLID, 0,
							 g_Colors[(_pPF->dwBorderColor & 0x1F) - 1]);
		LONG yTop = _ptCur.y;
		LONG yBot = yTop + _yHeight;
		if(pen)
		{
			pen = SelectPen(_hdc, pen);
			MoveToEx(_hdc, x,	   yTop , NULL);
			LineTo  (_hdc, xRight, yTop);
			if(!_fNextInTable)
			{
				MoveToEx(_hdc, x,	   yBot - 1, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -