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

📄 render.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				LineTo	(_hdc, xRight, yBot - 1);
			}
			h = 0;
			for(LONG i = 0; i <= _pPF->cTabCount; i++)
			{
				MoveToEx(_hdc, x + h, yTop, NULL);
				LineTo  (_hdc, x + h, yBot);
				h = LXtoDX(GetTabPos(_pPF->rgxTabs[i])) - dx;
			}
			if(pen)
				SelectPen(_hdc, pen);
		}
	}

	if (hdcSave)
	{
		RenderOffScreenBitmap(_osdc, hdcSave, xAdj, yAdj, yRcIgnored);
	}

	// Handle setting background color. We need to do this for each line 
	// because we return the background color to the default after each
	// line so that opaquing will work correctly.
	if (_crBackground != _crCurBackground)
	{
		// Tell the window the background color
		SetBkColor(_hdc, _crBackground);
	}

	Advance(cch);

   	// erase to right of render rect if necessary
	LONG xExtent = _fClipRightToView 
		? min(_rcView.right, _rcRender.right)
		: _rcRender.right;

	if(_fErase && ((_ptCur.x < xExtent) || _fFirstChunk))
	{
		SetClipLeftRight(xExtent - _ptCur.x);
		EraseTextOut(_hdc, &_rc);
		_ptCur.x = xExtent;
	}

	// increment y position to next line
	_ptCur.y = _rc.bottom;

	// return whether we rendered everything yet
	return _ptCur.y < BottomOfRender(_rcView, _rcRender);
}

/*
 *	CRenderer::UpdatePalette (pobj)
 *
 *	@mfunc
 *		Stores palette information so that we can render any OLE objects
 *		correctly in a bitmap.
 *
 *	@rdesc	
 *		None.
 */
void CRenderer::UpdatePalette(
	COleObject *pobj)		//@parm OLE object wrapper.
{
#ifndef PEGASUS
	LOGPALETTE *plogpalette = NULL;
	LOGPALETTE *plogpaletteMerged;
	IViewObject *pviewobj;

	// Get IViewObject interface information so we can build a palette
	// to render the object correctly.
	if (((pobj->GetIUnknown())->QueryInterface(IID_IViewObject, 
		(void **) &pviewobj)) != NOERROR)
	{
		// Couldn't get it, so we will pretend this didn't happen
		return;
	}

	// Get the logical palette information from the object
	if ((pviewobj->GetColorSet(DVASPECT_CONTENT, -1, NULL, NULL, 
			NULL, &plogpalette) != NOERROR) 
		|| (NULL == plogpalette))
	{
		// Couldn't get it, so we will pretend this didn't happen
		goto CleanUp;
	}

	// Do we have any palette entries yet?
	if (NULL == _plogpalette)
	{
		// No - just use the one returned.
		_plogpalette = plogpalette;
		goto CleanUp;
	}

	// We have had other palette entries. We just reallocate the table
	// and put the newest entry on the end. This is crude, we might
	// sweep the table and actually merge it. However, this code
	// should be executed relatively infrequently and therefore, crude
	// should be good enough.

	// Allocate a new table - Note the " - 1" in the end has to do with
	// the fact that LOGPALETTE is defined to have one entry already.
	plogpaletteMerged = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) * 
		(_plogpalette->palNumEntries + plogpalette->palNumEntries - 1)];

	if (NULL == plogpaletteMerged)
	{
		// Memory allocation failed. Just pretend it didn't happen.
		goto CleanTempPalette;
	}

	// Copy in original table.
	memcpy(&plogpaletteMerged->palPalEntry[0], &_plogpalette->palPalEntry[0],
		_plogpalette->palNumEntries * sizeof(PALETTEENTRY));

	// Put new data at the end.
	memcpy(&plogpaletteMerged->palPalEntry[_plogpalette->palNumEntries], 
		&plogpalette->palPalEntry[0],
		plogpalette->palNumEntries * sizeof(PALETTEENTRY));

	// Replace the current palette table with the merged table.
	delete _plogpalette;
	_plogpalette = plogpaletteMerged;

CleanTempPalette:

	delete plogpalette;

CleanUp:

	// Release the object we got since we don't need it any more.
	pviewobj->Release();
#endif
}

/*
 *	CRenderer::RenderChunk (&cchChunk, pstrToRender, cch)
 *
 *	@mfunc
 *		Virtual methods allowing to reduce the length of the chunk 
 *		(number of character rendered in one TextOut) and to render
 *		items interleaved in the text.
 *
 *	Arguments:
 *		cchChunk	in:  current length of the chunk
 * 					out: # of chars rendered if TRUE is returned
 *						 # of chars yet to render in the chunk if FALSE if returned	
 *
 *	@rdesc	
 *		TRUE if this method actually rendered the chunk, 
 * 		FALSE if it just updated cchChunk and rendering is still needed
 */
INLINE BOOL CRenderer::RenderChunk(
	LONG& cchChunk,				//@parm in: chunk cch; out: # chars rendered
								//  if return TRUE; else # chars yet to render
	const WCHAR *pstrToRender,	//@parm String to render up to cchChunk chars
	LONG cch)					//@parm # chars left to render on line
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::RenderChunk");

	LONG cchT;
	const TCHAR *pchT;
	COleObject *pobj = NULL;
	CObjectMgr *pobjmgr = NULL;
	LONG cchvalid, i;
	LONG objwidth, objheight;
    
	// If line has objects, reduce cchChunk to go to next object only
	if(_bFlags & fliHasOle)
	{
		pchT = pstrToRender;
		cchvalid = cchChunk;

		// Search for object in chunk
		for( i = 0; i < cchvalid && *pchT != WCH_EMBEDDING; i++ )
			pchT++;

		if( i == 0 )
		{
			// First character is the object so display the object
			pobjmgr = GetPed()->GetObjectMgr();
			if (pobjmgr)
			{
			    pobj = pobjmgr->GetObjectFromCp(GetCp());
			}    

			if( pobj )
			{
				pobj->MeasureObj(GetDp(), objwidth, objheight, _yDescent);
				SetClipLeftRight(_xWidth + objwidth);

				if (sysparam.FUsePalette()
					&& (_bFlags & fliUseOffScreenDC) 
					&& _pdp->IsMain())
				{
					// Keep track of the palette we need for rendering
					// the bit map.
					UpdatePalette(pobj);
				}

				pobj->DrawObj(_pdp, _hdc, _pdp->IsMetafile(), &_ptCur, &_rc);
				_ptCur.x += objwidth;
				_xWidth += objwidth;
			}

			cchChunk = 1;

			// Both tabs and object code need to advance the run pointer past
			// each character processed.
			Advance(1);

			_fFirstChunk = FALSE;
			return TRUE;
		}
		else 
		{
			// Limit chunk to character before object
			cchChunk -= cchvalid - i;
		}
	}

	// if line has tabs, reduce cchChunk
	if(_bFlags & fliHasTabs)
	{
		for(cchT = 0, pchT = pstrToRender;
			cchT < cchChunk && *pchT != TAB && *pchT != CELL
#ifdef SOFTHYPHEN
			&& *pchT != SOFTHYPHEN
#endif
			; pchT++, cchT++)
		{
			// this loop body intentionally left blank
		}
		
		if(!cchT)
		{
			// first char is a tab, render it and any that follow
#ifdef SOFTHYPHEN
			if(*pchT == SOFTHYPHEN)
			{
				if(cch == 1)				// Caller should render
					return FALSE;			//  soft hyphen at EOL
				Advance(1);					// Skip those within line
				cchChunk = 1;
			}
			else
#endif
				cchChunk = RenderTabs(cchChunk);
			Assert (cchChunk > 0);
			return TRUE;
		}

		cchChunk = cchT;		// Update cchChunk not to incl trailing tabs
	}

#ifdef PWD_JUPITER
    // GuyBark Jupiter 33730:
    // CRLF in tables are stored internally as a speical character
    // followed by a space. Display the special character as a space
    // in WordPad. When the document is streamed out later, we 
    // replace the two characters with CRLF again.
    if(_pPF->InTable())
    {
        // We're in a table.
        pchT     = pstrToRender;
        cchvalid = cchChunk;

        // Try to find the special character.
        for(i = 0; i < cchvalid && *pchT != PWD_CRLFINCELL; i++)
        {
            pchT++;
        }

        // The CRLF is at the start of this chunk.
        if( i == 0 )
        {
            TCHAR sz[2];

            sz[0] = ' ';
            sz[1] = '\0';

            // GuyBark Jupiter 38743: 
            // TextOut needs to know if this is the last chunk of text on the line.
            // Given that we always output two spaces for the secret CRLF, then the
            // first space cannot be the last chunk.
    		_fLastChunk = FALSE;

            // Display the special character as a space now.
            TextOut(sz, 1, FALSE);

            // Now move along with similar action to object processing above.
            cchChunk = 1;
            Advance(1);
            _fFirstChunk = FALSE;

            return TRUE;
        }
        else 
        {
            // Limit chunk to characters before CR.
            cchChunk -= cchvalid - i;
        }
    }
#endif // PWD_JUPITER

	return FALSE;
}		

/*
 *	CRenderer::SetClipLeftRight (xWidth)
 *
 *	@mfunc
 *		Helper to sets left and right of clipping/erase rect.
 *	
 *	@rdesc
 *		Sets _rc left and right	
 */
void CRenderer::SetClipLeftRight(
	LONG xWidth)		//@parm	Width of chunk to render
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::SetClipLeftRight");

	// Compute left of render/clip rect
	// a priori = left of render rect
	_rc.left = _rcRender.left;

	// limit to left of view rect if clip to view, selected 
	// or line starts left of that point
	if(_rc.left < _rcView.left && 
		(_fClipLeftToView || _fSelected || _fBackgroundColor
			|| _ptCur.x < _rcView.left))
	{
		_rc.left = _rcView.left;
		_fClipLeftToView = TRUE;
	}

	// limit to start of chunk if it's inside view
	if(_ptCur.x > _rcView.left)
	{
		if (!_fFirstChunk)
		{
			_rc.left = max(_ptCur.x, _rc.left);
		}
		else
		{
			// Tell TextOut that it should not invert the entire rectangle
			// since we are clearing the line for paragraph justification.
			_fRecalcRectForInvert = TRUE;				
		}
	}

	// We have set the rc.left for the first write so now we can ignore the 
	// problem of clearing to the beginning of the line.
	_fFirstChunk = FALSE;

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

	// limit to right of view rect if clip to view, selected 
	// or line extends beyond that point
	if(_rc.right > _rcView.right && 
		(_fClipRightToView || _fSelected || _fBackgroundColor
			|| _ptCur.x + xWidth > _rcView.right))
	{
		_rc.right = _rcView.right;
		_fClipRightToView = TRUE;
	}

	// limit to right of chunk if not last chunk or selected
	if(!_fLastChunk || _fSelected || _fBackgroundColor)
		_rc.right = min(_ptCur.x + xWidth, _rc.right);
}
	
/*
 *	CRenderer::TextOut (pch, cch)
 *
 *	@mfunc
 *		Render text in the current context of this CRenderer
 *
 *	@rdesc
 *		number of characters rendered 
 *
 *	@devnote
 *		Renders text only: does not do tabs or OLE objects
 */
LONG CRenderer::TextOut(
	const WCHAR *pch,	//@parm Text to render
	LONG cch,			//@parm Length of text to render
	BOOL fIMEHighlight)	//@parm highlight IME composition character
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CRenderer::TextOut");

	LONG		cchT;
	LONG		yOffsetForChar;

	// Variables used for calculating length of underline.
	LONG		xWidthSelPastEOL = 0;
	LONG		xWidthToDraw;
	LONG		xStart;
	LONG		xWidthClip;

	// Colors for hightlight
	COLORREF	crHighlight;
	COLORREF	crHighlightText;
	COLORREF	crPrevText = 0;
	COLORREF	crPrevBack = 0;

	CONVERTMODE cm = (CONVERTMODE)_pccs->_bConvertMode;

	// For hack around ExtTextOutW Win95 FE problems.
	if (cm != CM_LOWBYTE && _fEnhancedMetafileDC &&
		((VER_PLATFORM_WIN32_WINDOWS   == dwPlatformId) || 
		 (VER_PLATFORM_WIN32_MACINTOSH == dwPlatformId)))
	{
		cm = CM_WCTMB;
	}
	else if (cm != CM_LOWBYTE && _pdp->IsMetafile() &&
		OnWinNTFE())
	{
		// FE NT metafile ExtTextOutW hack.
		cm = CM_WCTMB;
	}
	else if( (VER_PLATFORM_WIN32_WINDOWS == dwPlatformId) &&
		_pdp->IsMetafile() && !_fEnhancedMetafileDC )
	{
		//Win95 can't handle TextOutW to regular metafiles
		cm = CM_WCTMB;
	}
		
	
	// Options for ExtTextOut - assume render line of same format 
	UINT		fuOptions = ETO_CLIPPED | ETO_OPAQUE;
	LONG		xEraseMin = 0;
	LONG		xWidth;
	LONG		tempwidth;
	int			bkModeOld = 0;

	// Note the clipping depends on type of output. Default to clip rectangle
	// calculated by SetClipLeftRight - this is used by both regular rendering
	// and off screen rendering.
	RECT *		prcForClip = &_rc;

	// Rectangle used for clipping when a transparent render.
	RECT		rcClipTransparent;

	if (!_fErase)
	{
		if (_crBackground == _crCurBackground)
		{
			// Assume this is off screen - don't need to clip at all
			fuOptions = 0;

			if (!_fUseOffScreenDC)
			{
				// Transparent render. We need to clip to the total view.
				fuOptions = ETO_CLIPPED;
			}
		}
	}
	else if (_fLastLine && (_crBackground != _crCurBackground))
	{
		// We want to make sure that we don't use the background color for 
		// the text to opqaue anything but the current line so...
		if (_rc.bottom > _ptCur.y + _yHeight)
		{
			_rc.bottom = _ptCur.y + _yHeight;
		}
	}


	// Trim all nondisplayable linebreaking chars off end
	while(cch && IsASCIIEOP(pch[cch - 1]))
		cch--;

	if( !_fLastChunk || _xWidthLine == -1 )
	{
		// Measure width of text to write so next point to write can be
		// calculated.
		xWidth = 0;

⌨️ 快捷键说明

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