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

📄 htmlparse.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		case pVAlign:
			valg = GetAlignmentFromString( strParam, valg );
			break;
		}
	}

	if( m_stkTable.GetSize() )
	{
		m_stkTable.Top()->NewRow( valg );
	}
}


void CHTMLParse::OnGotTableCell( const CParameters &pList )
{
	// Ensure that we are processing documents properly.
	// close the previous cell if it was left open...
	if (m_stkInTableCell.GetSize())
	{
		if (m_stkInTableCell.Top())
			OnGotEndTableCell();
		m_stkInTableCell.Top() = true;
	}

	int nWidth = 0;
	int nHeight = 0;
	bool bNoWrap = false;
	bool bTransparent = true;
	COLORREF crBorder = RGB(0,0,0);
	COLORREF crBgColor = RGB( 255, 255, 255 );	// Not really used.
	COLORREF crBorderLight = m_pDefaults->m_crBorderLight;
	COLORREF crBorderDark = m_pDefaults->m_crBorderDark;
	bool bBorderDarkSet = false;
	bool bBorderLightSet = false;

	CHTMLParse::Align alg = knDefaultTableCellAlignment;
	CHTMLParse::Align valg = m_stkTable.Top()->GetCurrentRow()->m_valg;

	// Get defaults from the current table
	// Could really ignore everything if we are not in a table!
	if( m_stkTable.GetSize() )
	{
		CHTMLTable* pTab = m_stkTable.Top();
		crBorderLight = pTab->m_crBorderLight;
		crBorderDark = pTab->m_crBorderDark;
	}

	const UINT uParamSize = pList.GetSize();
	for( UINT n = 0; n < uParamSize; n++ )
	{
		const CStaticString &strParam = pList[n].m_strValue;
		switch( pList[n].m_param )
		{
		case pWidth:
			nWidth = GetNumberParameterPercent( strParam, nWidth );
			break;

		case pHeight:
			nHeight = GetNumberParameter( strParam, nHeight );
			break;

		case pAlign:
			alg = GetAlignmentFromString( strParam, alg );
			break;

		case pVAlign:
			valg = GetAlignmentFromString( strParam, alg );
			break;

		//  richg - 19990224 - Add support for NOWRAP
		case pNoWrap:
			bNoWrap = true;
			break;

		case pBColor:
			crBgColor = GetColourFromString( strParam, crBgColor );
			bTransparent = false;
			break;

		case pBorderColor:
			crBorder = GetColourFromString( strParam, crBorder );
			if ( !bBorderDarkSet )
				crBorderDark = crBorder;
			if ( !bBorderLightSet )
				crBorderLight = crBorder;
			break;

		case pBorderColorLight:
			crBorderLight = GetColourFromString( strParam, crBorderLight );
			bBorderLightSet = true;
			break;

		case pBorderColorDark:
			crBorderDark = GetColourFromString( strParam, crBorderDark );
			bBorderDarkSet = true;
			break;

		}
	}

	//
	//	If there is a table to add our cell to...
	if( m_stkTable.GetSize() )
	{
		CHTMLTableCell *pCell = new CHTMLTableCell( m_pDefaults, nWidth, nHeight, bNoWrap, bTransparent, crBgColor, crBorderDark, crBorderLight, valg );
		// Copy the current documents link colors into the new document
		pCell->m_crLink = m_pDocument->m_crLink;
		pCell->m_crLinkHover = m_pDocument->m_crLinkHover;
		// Push it onto the document stack
		m_stkDocument.Push( m_pDocument );

		// TRACENL("Document Stack Pushed. %d\n", m_stkDocument.GetSize());

		m_pDocument = pCell;
		m_pProp->nAlignment = alg;
		CreateNewParagraph( 0, 0, m_pProp->nAlignment );
		m_stkTable.Top()->AddCell( pCell );
	}
}


void CHTMLParse::OnGotEndTableCell()
{
	CreateNewTextObject();
	if( m_stkDocument.GetSize() )
	{
		m_pDocument = m_stkDocument.Pop();
		// TRACENL("Document Stack Popped. %d\n", m_stkDocument.GetSize());
	}
	else
	{	
		TRACE( _T("Got an end table cell but no document stack left\n") );
	}
	if (m_stkInTableCell.GetSize())
		m_stkInTableCell.Top() = false;
}


void CHTMLParse::OnGotEndTableRow()
{
	if( m_stkInTableCell.GetSize() && m_stkInTableCell.Top() )
		OnGotEndTableCell();
}

void CHTMLParse::CreateList( bool bOrdered )
{
	CreateNewTextObject();
	CreateNewParagraph( 0, 0, CHTMLParse::algLeft );

	CHTMLList *pList = new CHTMLList( bOrdered );
	m_stkList.Push( pList  );
	m_pDocument->CurrentParagraph()->AddItem( m_stkList.Top() );

	// Create the default first item
	CHTMLListItem *pItem = new CHTMLListItem( m_pDefaults, false, m_pProp->szFaceName, m_pProp->nSize, m_pProp->bBold, m_pProp->bItalic, m_pProp->bUnderline, m_pProp->bStrikeThrough, m_pProp->m_crFore );	// Not bulleted
	// Copy the current documents link colors into the new document
	pItem->m_crLink = m_pDocument->m_crLink;
	pItem->m_crLinkHover = m_pDocument->m_crLinkHover;
	m_stkDocument.Push( m_pDocument );
	m_pDocument = pItem;
	CreateNewParagraph( 0, 0, CHTMLParse::algLeft );
	m_stkList.Top()->AddItem( pItem ); 
}

void CHTMLParse::OnGotUnorderedList( const CParameters & /* pList */ )
{
	CreateList( false );
}

void CHTMLParse::OnGotOrderedList( const CParameters & /* pList */ )
{
	CreateList( true );
}

void CHTMLParse::OnGotListItem( const CParameters & /* pList */ )
{
	// </li> is completely ignored by IE4, and by NetScape
	// Additionally, items occuring after the <ol> or <ul> and
	// before the first <li> are positioned as if they were preceeded
	// by <li>, but the bullet is not shown. Empty <LI> tags DO show their
	// bullets.
	// In order to handle these cases, do the following:
	// For a new list, create the initial list item, but flag it as
	// unbulleted. When a <LI> is reached, determine if there is
	// exactly one item in the list. If so, and it is empty, Mark the
	// existing item as bulleted, and use it... otherwise, proceed by adding
	// another list item.
	// See that we are in a list, otherwise, ignore it...
	if ( m_stkList.GetSize() )
	{
		CreateNewTextObject();
		// See if we can use the existing item
		if ( m_stkList.Top()->m_arrItems.GetSize() == 1 && 
			!m_stkList.Top()->m_arrItems[0]->m_bBullet &&  
			m_stkList.Top()->m_arrItems[0]->IsEmpty() )
		{
			// There is en emptry entry that is not bulleted
			m_stkList.Top()->m_arrItems[0]->m_bBullet = true;
			// Nothing more to do!
			return;
		}
		// We are in a list and creating a new item, close the previous item
		CreateNewTextObject();
		if( m_stkDocument.GetSize() )
		{
			m_pDocument = m_stkDocument.Pop();
		}
		// Need to create a new item...
		CHTMLListItem *pItem = new CHTMLListItem( m_pDefaults, true, m_pProp->szFaceName, m_pProp->nSize, m_pProp->bBold, m_pProp->bItalic, m_pProp->bUnderline, m_pProp->bStrikeThrough, m_pProp->m_crFore );	// bulleted
		// Copy the current documents link colors into the new document
		pItem->m_crLink = m_pDocument->m_crLink;
		pItem->m_crLinkHover = m_pDocument->m_crLinkHover;
		m_stkDocument.Push( m_pDocument );
		m_pDocument = pItem;
		CreateNewParagraph( 0, 0, CHTMLParse::algLeft );
		m_stkList.Top()->AddItem( pItem ); 
	}
}


void CHTMLParse::OnGotEndListItem()
{
	// Do nothing.
}

void CHTMLParse::OnGotEndList()
{
	// See that we are in a list, otherwise, ignore it...
	if ( m_stkList.GetSize() )
	{
		// Close the last item...
		CreateNewTextObject();
		if( m_stkDocument.GetSize() )
		{
			m_pDocument = m_stkDocument.Pop();
		}
		CreateNewParagraph( 0, 0, CHTMLParse::algLeft );
		// Close this list.
		m_stkList.Pop();
	}
}


void CHTMLParse::OnGotBlockQuote( const CParameters & /* pList */ )
{
	/*
		A Blockquote is treated as a sub document with different
		margins. This is fairly straightforward.
	*/
	CreateNewTextObject();
	CreateNewParagraph( 0, 0, m_pProp->nAlignment );

	CHTMLBlockQuote *pBQ = new CHTMLBlockQuote( m_pDefaults );
	m_pDocument->CurrentParagraph()->AddItem( pBQ );
	// Make the sub document the main document
	m_stkDocument.Push( m_pDocument );
	m_pDocument = pBQ->m_pDoc;
	CreateNewParagraph( 0, 0, m_pProp->nAlignment);
}


void CHTMLParse::OnGotEndBlockQuote()
{
	/*
		Cause a document stack pop if possible...
	*/
	CreateNewTextObject();
	if( m_stkDocument.GetSize() )
	{
		m_pDocument = m_stkDocument.Pop();
	}
	else
	{
		TRACE( _T("At </BLOCKQUOTE> but document stack is empty.\n") );
	}
	CreateNewParagraph(0, 0, m_pProp->nAlignment);
}



void CHTMLParse::OnGotAddress( const CParameters & /* pList */ )
//
//	Fundtionally the same as BLOCKQUOTE but with italics
{
	CreateNewTextObject();
	CreateNewParagraph( 0, 0, m_pProp->nAlignment );

	CreateNewProperties();
	m_pProp->bItalic = true;

	CHTMLBlockQuote *pBQ = new CHTMLBlockQuote( m_pDefaults );
	m_pDocument->CurrentParagraph()->AddItem( pBQ );
	// Make the sub document the main document
	m_stkDocument.Push( m_pDocument );
	m_pDocument = pBQ->m_pDoc;
	CreateNewParagraph( 0, 0, m_pProp->nAlignment);
}


void CHTMLParse::OnGotEndAddress()
{
	CreateNewTextObject();
	if( m_stkDocument.GetSize() )
	{
		m_pDocument = m_stkDocument.Pop();
	}
	else
	{
		TRACE( _T("At </BLOCKQUOTE> but document stack is empty.\n") );
	}
	PopPreviousProperties();
	CreateNewParagraph(0, 0, m_pProp->nAlignment);
}


void CHTMLParse::GetFontName( LPTSTR pszBuffer, int nBufferSize, const CStaticString &strFontNameSpec )
//
//	Get the font name from a font name spec.
//	This consists of comma delimited font names "tahoma,arial,helvetica"
//	We need to find
{
	static const TCHAR cComma = _T(',');
	if( strFontNameSpec.GetData() )
	{
		LPCTSTR pcszFontNameSpec = strFontNameSpec.GetData();
		//	Set our string to empty
		*pszBuffer = _T('\000');

		if( strFontNameSpec.Find( cComma ) )
		{
			//
			//	Iterate over the passed font names, copying each font name as we go.
			LPCTSTR pcszFontNameSpecEnd = strFontNameSpec.GetEndPointer();
			LPCTSTR pszFontNameStart, pszFontNameEnd;
			pszFontNameStart = pszFontNameEnd = pcszFontNameSpec;

			while( pszFontNameStart < pcszFontNameSpecEnd )
			{
				//
				//	Find the end of the first font.
				while( pszFontNameEnd < pcszFontNameSpecEnd && *pszFontNameEnd != cComma )
					pszFontNameEnd++;

				if( pszFontNameEnd - pszFontNameStart && pszFontNameEnd - pszFontNameStart < nBufferSize)
				{
					StringClass strFontName( pszFontNameStart, pszFontNameEnd - pszFontNameStart );

					//
					//	We have our font name, now determine whether the font exists or not.
					if( DoesFontExist( strFontName ) )
					{
						//	It does, then we get out of here. If the font doesn't exist then we simply
						//	continue looping around.
						_tcscpy( pszBuffer, strFontName );
						return;
					}
				}


				//
				//	Skip past the white space and commas
				while( pszFontNameEnd < pcszFontNameSpecEnd && ( isspace( *pszFontNameEnd ) || *pszFontNameEnd == cComma ) )
					pszFontNameEnd++;

				pszFontNameStart = pszFontNameEnd;
			}
		}
		else
		{
			StringClass strFontName( strFontNameSpec.GetData(), strFontNameSpec.GetLength() );
			if( DoesFontExist( strFontName ) )
			{
				//	It does, then we get out of here. If the font doesn't exist then we simply
				//	continue looping around.
				_tcscpy( pszBuffer, strFontName );
			}
			else
			{
				_tcscpy( pszBuffer, m_pDefaults->m_strFontName );
			}
		}

	}
	else
	{
		_tcscpy( pszBuffer, m_pDefaults->m_strFontName );
	}

	//
	//	If we drop out here it means that none of the user requested fonts exist on the system.
}

static int CALLBACK EnumFontFamExProc( ENUMLOGFONTEX * /*lpelfe*/, NEWTEXTMETRICEX * /*lpntme*/, int /*FontType*/, LPARAM /*lParam*/ )
{
	return -1;
}


bool CHTMLParse::DoesFontExist( const StringClass &strFontName )
//
//	Determine if the font exists in our map and return that result.
//	If it doesn't exist in our map then ask the system if the font exists and add
//	that known state to our map.
{
	bool *pb = g_mapFontName.Lookup( strFontName );
	if( pb )
	{
		return *pb;
	}

	LOGFONT lf = { 0 };
	_tcscpy( lf.lfFaceName, strFontName );
	lf.lfCharSet = m_pMasterDocument->m_cCharSet;

	CDrawContext dc;
	bool bExists = false;

	//
	//	NOTE: If the font doesn't exist EnumFontFamiliesEx returns 1 - originally I had my callbcak return
	//	true or false. This didn't work if the font didn't exist. Now the callback returns -1 if the font
	//	exists.
	if( EnumFontFamiliesEx( dc.GetSafeHdc(), &lf, (FONTENUMPROC)EnumFontFamExProc, 0, 0 ) == -1 )
		bExists = true;
	g_mapFontName.SetAt( strFontName, bExists );
#ifdef _DEBUG
	if( !bExists )
	{
		TRACE( "Font doesn't exist '%s'\n", strFontName );
	}
#endif	//	_DEBUG
	return bExists;
}


void CHTMLParse::OnGotMeta( const CParameters &pList )
{
	const UINT uParamSize = pList.GetSize();
	for( UINT n = 0; n < uParamSize; n++ )
	{
		const CStaticString &strParam = pList[n].m_strValue;
		switch( pList[n].m_param )
		{
		case pContent:
			{
				LPCTSTR pcszEnd = strParam.GetData() + strParam.GetLength();
				static const TCHAR szCharSet[] = _T("charset");
				LPCTSTR p = stristr( (LPTSTR)strParam.GetData(), szCharSet );
				if( p )
				{
					//
					//	We have a charset, so next we need to decode it
					p += countof( szCharSet ) - 1;
					while( p < pcszEnd && ( isspace( *p ) || *p == _T('=') ) )
						p++;
					if( p < pcszEnd )
					{
						const CStaticString str( p, pcszEnd - p );
						m_pDocument->m_cCharSet = DecodeCharset( str );
					}
				}
			}
			break;

		case pHTTPEquiv:
			//TRACE( "pHTTPEquiv %s\n", strParam );
			break;
		}
	}
}

⌨️ 快捷键说明

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