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

📄 render.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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 - RENDER.C |
 *		CRenderer class
 *	
 *	Authors:
 *		Original RichEdit code: David R. Fulmer
 *		Christian Fortini
 *		Murray Sargent
 *
 */

#include "_common.h"
#include "_render.h"
#include "_font.h"
#include "_disp.h"
#include "_edit.h"
#include "_select.h"
#include "_objmgr.h"
#include "_coleobj.h"
#include "_ime.h"

// Default colors for background and text on window's host printer
const COLORREF RGB_WHITE = RGB(255, 255, 255);
const COLORREF RGB_BLACK = RGB(0, 0, 0);

ASSERTDATA

static HBITMAP g_hbitmapSubtext = 0;
static HBITMAP g_hbitmapExpandedHeading = 0;
static HBITMAP g_hbitmapCollapsedHeading = 0;
static HBITMAP g_hbitmapEmptyHeading = 0;

// GuyBark 34205: Added the small bitmap handling.
static HBITMAP g_hbitmapExpandedSmallHeading = 0;
static HBITMAP g_hbitmapCollapsedSmallHeading = 0;
static HBITMAP g_hbitmapEmptySmallHeading = 0;

HRESULT InitializeOutlineBitmaps()
{
    g_hbitmapSubtext =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_SUBTEXT));
    g_hbitmapExpandedHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_EXPANDED_HEADING));
    g_hbitmapCollapsedHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_COLLAPSED_HEADING));
    g_hbitmapEmptyHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_EMPTY_HEADING));

    // GuyBark Jupiter 34205: The above bitmaps look pretty bad when the zoom
    // stretches them smaller. There is no SetStretchBltMode() on the device, 
    // to help preserve the black at the expense of the white. So load up some 
    // bitmaps with thicker black lines, to use if the current zoom is < 100%. 
    // Not an ideal solution, but probably the only thing we can do to make 
    // the outline view look a little nicer at low zoom levels.

    g_hbitmapExpandedSmallHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_EXPANDEDSM_HEADING));
    g_hbitmapCollapsedSmallHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_COLLAPSEDSM_HEADING));
    g_hbitmapEmptySmallHeading =
        LoadBitmap(hinstRE, MAKEINTRESOURCE(BITMAP_ID_EMPTYSM_HEADING));

    if (!g_hbitmapSubtext ||
        !g_hbitmapExpandedHeading ||
        !g_hbitmapCollapsedHeading ||
        !g_hbitmapEmptyHeading ||
        !g_hbitmapExpandedSmallHeading ||
        !g_hbitmapCollapsedSmallHeading ||
        !g_hbitmapEmptySmallHeading)
    {
        return ERROR_FILE_NOT_FOUND; // REVIEW: better error?
    }
    return NOERROR;
}

/*
 * 	IsEnhancedMetafileDC( hDC )
 *
 *	@mfunc
 *		Check if hDC is a Enhanced Metafile DC.
 *		There is work around the Win95 FE ::GetObjectType() bug.
 *
 *	@rdesc
 *		Returns TRUE for EMF DC.
 */
BOOL IsEnhancedMetafileDC (
	HDC hDC)			//@parm handle to device context 
{
	return W32->IsEnhancedMetafileDC( hDC );
}

CRenderer::CRenderer (const CDisplay * const pdp) :
	CMeasurer (pdp)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::CRenderer");

	Init();
}	
 
CRenderer::CRenderer (const CDisplay * const pdp, const CRchTxtPtr &tp) :
	CMeasurer (pdp, tp)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::CRenderer");

	Init();
}

/*
 *	CRenderer::Init
 *
 *	@mfunc
 *		initialize everything to zero
 */
void CRenderer::Init()
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::Init");

	static RECT zrect = { 0, 0, 0, 0 };
	_rcView		= zrect;
	_rcRender	= zrect;	  
	_rc			= zrect;
	_xWidthLine = 0;
	_dwFlags	= 0;
	_ptCur.x	= 0;
	_ptCur.y	= 0;
	_crBackground = CLR_INVALID;

	CTxtSelection *psel = GetPed()->GetSel();
	_fRenderSelection = psel && psel->GetShowSelection();
	
	// Get accelerator offset if any
	_cpAccelerator = GetPed()->GetCpAccelerator();

	_plogpalette = NULL;
}
 
INLINE void EraseTextOut(HDC hdc, const RECT *prc)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "EraseTextOut");

	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, prc, NULL, 0, NULL);
}

/*
 * 	CRenderer::StartRender (&rcView, &rcRender, yHeightBitmap)
 *
 *	@mfunc
 *		Prepare this renderer for rendering operations
 *
 *	@rdesc
 *		FALSE if nothing to render, TRUE otherwise	
 */
BOOL CRenderer::StartRender (
	const RECT &rcView,			//@parm View rectangle
	const RECT &rcRender,		//@parm Rectangle to render
	const LONG yHeightBitmap)	//@parm Height of bitmap for offscreen DC
{
	BOOL fTransparent;
	CTxtEdit *ped = GetPed();
	BOOL fInOurHost = ped->fInOurHost();
						   
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::StartRender");

	// If this a metafile or a transparent control we better not be trying to
	// render off screen. Therefore, the bit map height must be 0.
	AssertSz(!((_pdp->IsMetafile() || ped->_fTransparent) 
		&& (yHeightBitmap != 0)),
			"CRenderer::StartRender metafile and request for off screen DC");
	
	if(!_hdc)
	{
		_hdc = _pdp->GetDC();
		_hdcMeasure = _pdp->GetMeasureDC(&_yMeasurePerInch);
	}

	AssertSz(_hdc, "CRenderer::StartRender() - No rendering DC");

	// Set view and rendering rects
	_rcView = rcView;
	_rcRender = rcRender;

	// Init flags indicating whether to erase around each side
	// of the view rect.
	_fClipLeftToView 	= 
	_fClipRightToView 	= 
	_fClipTopToView 	= 
	_fClipBottomToView 	= FALSE;

	fTransparent = ped->_fTransparent;

	if (!fInOurHost || !_pdp->IsPrinter())
	{
		// If we are displaying to a window, or we are not in the window's
		// host, we use the colors specified by the host. For text and
		// foreground.
		_crBackground = ped->TxGetBackColor();
		_crTextColor = ped->TxGetForeColor();
	}
	else
	{
		// When the window's host is printing, the default colors are white
		// for the background and black for the text.
		_crBackground = RGB_WHITE;
		_crTextColor = RGB_BLACK;
	}

	SetBkColor(_hdc, _crBackground);
	SetTextColor(_hdc, _crTextColor);

	if (!_pdp->IsMetafile() && _pdp->IsMain())
	{
		// This isn't a metafile so we do the usual thing.

		// Set flag indicating whether we can safely erase the background
		_fErase = !fTransparent;
	}
	else
	{
		// This is a metafile or a printer so clear the render rectangle 
		// and then pretend we are transparent.
		// NOTE: we do this special behavior for printer's because Win95
		// seems to have a bug where it cannot render bitmaps to printers.
		_fErase = FALSE;

		if (!fTransparent)
		{
			// If the control is not transparent we clear the display.
			EraseTextOut(_hdc, &rcRender);
		}

		fTransparent = TRUE;
	}

	// Set background mode and color
	SetBkMode(_hdc, fTransparent ? TRANSPARENT : OPAQUE);

	// Set text alignement
	// Note: here we want the alignment to be top and left, which is usually
	// what the default of the DC is.  Performance testing showed that if we
	// set base line alignment, the first call to set base line alignment 
	// takes ALOT of time.  So, its better to compute where the base line
	// should go and draw top left, than it is to figure where the top left
	// is and draw base line.
	if (GetTextAlign( _hdcMeasure ) != (TA_TOP | TA_LEFT))
		SetTextAlign(_hdc, TA_TOP | TA_LEFT);

	// Since we haven't had a chance to set the background color
	// assume that the default and the current are the same.
	_crCurBackground = _crBackground;

	// Assume that we won't use an offscreen DC
	_fUseOffScreenDC = FALSE;

	AssertSz((yHeightBitmap == 0) || !fTransparent,
		"CRenderer::StartRender off screen requested with transparent");

	if (yHeightBitmap != 0)
	{
		HPALETTE hpal = fInOurHost
			? ped->TxGetPalette()
			: (HPALETTE) GetCurrentObject(_hdcMeasure, OBJ_PAL);

		// Create an off screen DC for rendering
		if (_osdc.Init(
			_hdcMeasure, 
			_rcRender.right - _rcRender.left,
			yHeightBitmap,
			_crBackground) == NULL)
		{
			return FALSE;
		}

		_osdc.SelectPalette(hpal);
		
		// We are using off screen rendering
		_fUseOffScreenDC = TRUE;
	}

	// If this is not the main display or it is a metafile
	// we want to ignore the logic to render selections
	if (!_pdp->IsMain() || _pdp->IsMetafile())
	{
		_fRenderSelection = FALSE;
	}

	// For hack around ExtTextOutW Win95FE Font and EMF problems.
	_fEnhancedMetafileDC = ((VER_PLATFORM_WIN32_WINDOWS == dwPlatformId) && IsEnhancedMetafileDC(_hdc));

	return TRUE;
}

void CRenderer::EndRender()
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::EndRender");

	_rc = _rcRender;
	
	AssertSz(_hdc, "CRenderer::EndRender() - No rendering DC");

	if(_fErase)
	{
		if(_ptCur.y < _rcRender.bottom)
		{
			_rc.top = _ptCur.y;
			EraseTextOut(_hdc, &_rc);
			_rc.top = _rcRender.top;
		}

		if(_fClipLeftToView && _rc.left < _rcView.left)
		{
			_rc.right = _rcView.left;
			EraseTextOut(_hdc, &_rc);
			_rc.right = _rcRender.right;
		}

		if (_fClipTopToView && _rc.top < _rcView.top)
		{
			_rc.bottom = _rcView.top;
			EraseTextOut(_hdc, &_rc);
			_rc.bottom = _rcRender.bottom;
		}

		if (_fClipRightToView && _rc.right > _rcView.right)
		{
			_rc.left = _rcView.right;
			EraseTextOut(_hdc, &_rc);
			_rc.left = _rcRender.left;
		}
	}

	// We need to dump the font - Done here because methods in CMeasurer will (should)
	// never select the font.
	if (_pccs && _hdc)
	{
		HFONT hfontOld = (HFONT)SelectObject(_hdc, GetStockObject(SYSTEM_FONT));
		Assert(hfontOld == _pccs->_hfont);
		// Drop _pccs
		_pccs->Release();
		// End further processing on the font reference.
		_pccs = NULL;
	}
}

/*
 *	CRenderer::NewLine (&li)
 *
 *	@mfunc
 *		Init this CRenderer for rendering the specified line
 */
void CRenderer::NewLine (const CLine &li)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::NewLine");

	*this = li;

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

	_xWidthLine = _xWidth;
	_xWidth = 0;
	_ptCur.x = _xLeft + _rcView.left - _pdp->GetXScroll();
	_fFirstChunk = TRUE;
	_fRecalcRectForInvert = FALSE;
	_fSelected = FALSE;
}

/*
 *	CRenderer::CalcHeightBitmap(yHeightToRender)
 *
 *	@mfunc
 *		Calculate the height of the bitmap needed for rendering
 *
 *	@rdesc
 *		Height of bitmap needed for rendering
 *
 *	@devnote
 *		Common code to calculate the size of a bitmap needed. It takes
 *		a parameter because it is useful for one of the caller routines 
 *		to calculate this value.
 */
LONG CRenderer::CalcHeightBitmap(
	LONG yHeightToRender)
{
	LONG yHeightOfBitmap = min(_yHeight, yHeightToRender);

	if (_rc.top < _ptCur.y)
	{
		// If the top of the area to render is above the starting point
		// of where to render, we add that in so that that area will get
		// cleared out by the bitblt as well rather than having an extra
		// call to ExtTextOut to do so.
		yHeightOfBitmap += (_ptCur.y - _rc.top);
	}

	return yHeightOfBitmap;
}

/*
 *	CRenderer::SetUpOffScreenDC(osdc, xAdj, yAdj, yRcIgnored)
 *
 *	@mfunc
 *		Setup the renderer for using an off screen DC
 *
 *	@rdesc
 *		NULL - an error occurred<nl>
 *		~NULL - DC to save 
 *
 *	@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 HDC CRenderer::SetUpOffScreenDC(
	COffScreenDC& osdc,	//@parm off screen DC object
	LONG& xAdj,			//@parm offset to x 
	LONG& yAdj,			//@parm offset to y 
	LONG& yRcIgnored)	//@parm part of display rectangle that not processed
{
	// Save the render DC
	HDC hdcSave = _hdc;
	LONG yHeightRC = _rc.bottom - _rc.top;
	LONG yHeightOfBitmap = CalcHeightBitmap(yHeightRC);

#ifdef PWD_JUPITER
	// GuyBark Jupiter 35187:
	// Get the current text color for the current render dc.
	COLORREF colText = GetTextColor(_hdc);
#endif // PWD_JUPITER

	// Replace the render DC with an off screen DC
	_hdc = _osdc.GetDC();

	if (NULL == _hdc)
	{
		// There is no off screen renderer 

		// This better be a line marked for a one time off screen rendering 
		// that wasn't. Note: standard cases for this happening are a line
		// that would have been displayed is scrolled off the screen 
		// because an update of the selection.
		AssertSz((_bFlags & fliOffScreenOnce) != 0,
			"CRenderer::SetUpOffScreenDC Unexpected off screen DC failure");

		_hdc = hdcSave;
		return NULL;
	}

	AssertSz(!GetPed()->_fTransparent, 
		"CRenderer::SetUpOffScreenDC off screen render of tranparent control");

	if (_pccs != NULL)
	{
		// There is current a character format for the run so we need to
		// get in sync with that since the off screen DC isn't necessarily
		// set to that font.

		// Get the character format
		const CCharFormat *pcf = GetCF();

		// Set up the font.
		SetFontAndColor(pcf);
	}


	// We are rendering to a tranparent background
	_fErase = FALSE;

	// Prepare for clear

⌨️ 快捷键说明

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