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

📄 wg_renderedstring.cpp

📁 一个小巧的嵌入式图形系统wGUI, 可以用VC编译
💻 CPP
字号:
// wg_renderedstring.cpp//// CRenderedString implementation////// Copyright (c) 2002 Rob Wiskow// rob-dev@boxedchaos.com//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//#include "wgui_include_config.h"#include "wg_renderedstring.h"#include "wg_painter.h"#include "wg_error.h"#include <algorithm>namespace wGui{CRenderedString::CRenderedString(CFontEngine* pFontEngine, const std::string& sString, EVAlign eVertAlign, EHAlign eHorzAlign) :	m_pFontEngine(pFontEngine),	m_sString(sString),	m_eVertAlign(eVertAlign),	m_eHorzAlign(eHorzAlign),	m_bCachedMetricsValid(false),	m_MaskChar(' '),	m_MaxFontHeight(-1){	if (! m_pFontEngine)	{		throw(Wg_Ex_App("CRenderedString::CRenderedString : Bad pFontEngine pointer!"));	}}void CRenderedString::Draw(SDL_Surface* pSurface, const CRect& BoundingRect, const CPoint& OriginPoint, const CRGBColor& FontColor) const{	CPoint OriginOffset;	std::vector<CRect> CharacterRects;	GetMetrics(0, &OriginOffset, &CharacterRects);	for (unsigned int i = 0; i < m_sString.size(); ++i)	{		FT_BitmapGlyphRec* pGlyph;		if (m_MaskChar == ' ')		{			pGlyph = m_pFontEngine->RenderGlyph(m_sString[i]);		}		else		{			pGlyph = m_pFontEngine->RenderGlyph(m_MaskChar);		}		CPainter Painter(pSurface, CPainter::PAINT_NORMAL);		for (int y = 0; y < pGlyph->bitmap.rows; ++y)		{			for (int x = 0; x < pGlyph->bitmap.width; ++x)			{				unsigned char* PixelOffset = pGlyph->bitmap.buffer + y * pGlyph->bitmap.width + x;				if (*PixelOffset != 0x00)				{					CRGBColor PixelColor(FontColor.red, FontColor.green, FontColor.blue, *PixelOffset);					CPoint PixelPoint(CPoint(x + pGlyph->left, y) + OriginPoint + OriginOffset + CharacterRects[i].TopLeft());					if (BoundingRect.HitTest(PixelPoint) == CRect::RELPOS_INSIDE)					{						Painter.DrawPoint(PixelPoint, PixelColor);					}				}			}		}	}}unsigned int CRenderedString::GetMaxFontHeight(){	if (m_MaxFontHeight < 0)	{		int maxHeight=0;		FT_Glyph_Metrics* pMetrics;		for(int i=0; i < 256; i++)		{			pMetrics = m_pFontEngine->GetMetrics((char)i);			if ((pMetrics->height >> 6) > maxHeight)			{				maxHeight = (pMetrics->height >> 6);			}			//maxHeight = std::max(maxHeight, pMetrics->height);		}		m_MaxFontHeight = maxHeight;	}	return m_MaxFontHeight;}void CRenderedString::GetMetrics(CPoint* pBoundedDimensions, CPoint* pOriginOffset, std::vector<CRect>* pCharacterRects) const{	if (! m_bCachedMetricsValid)	{		m_CachedCharacterRects.clear();		int iMinY = 0;		int iMaxY = 0;		int iLength = 0;		for (unsigned int i = 0; i < m_sString.size(); ++i)		{			FT_Glyph_Metrics* pMetrics;			if (m_MaskChar == ' ')			{				pMetrics = m_pFontEngine->GetMetrics(m_sString[i]);			}			else			{				pMetrics = m_pFontEngine->GetMetrics(m_MaskChar);			}			//FT_Glyph_Metrics* pMetrics = m_pFontEngine->GetMetrics(m_sString[i]);			if ((pMetrics->horiBearingY - pMetrics->height) < iMinY)			{				iMinY = pMetrics->horiBearingY - pMetrics->height;			}			if (pMetrics->horiBearingY > iMaxY)			{				iMaxY = pMetrics->horiBearingY;			}			iLength += (pMetrics->horiAdvance);			// The top and bottom values of the rect are not actually in rect coordinates at this point, since iMaxY and iMinY are not yet know			m_CachedCharacterRects.push_back(				CRect((iLength - pMetrics->horiAdvance) >> 6, pMetrics->horiBearingY >> 6, iLength >> 6, pMetrics->height >> 6));		}		iMinY = iMinY >> 6;		iMaxY = iMaxY >> 6;		iLength = iLength >> 6;		// now fix the top and bottom values of the rects		for(std::vector<CRect>::iterator iter = m_CachedCharacterRects.begin(); iter != m_CachedCharacterRects.end(); ++iter)		{			iter->SetTop(iMaxY - iter->Top());			iter->SetBottom(iter->Top() + iter->Bottom());		}		// Tack an empty rect on the end		m_CachedCharacterRects.push_back(CRect(iLength, iMaxY, iLength, iMinY));		m_CachedBoundedDimensions = CPoint(iLength, iMaxY - iMinY);		switch (m_eHorzAlign)		{		case HALIGN_CENTER:			m_OriginOffset.SetX(-iLength / 2);			break;		case HALIGN_RIGHT:			m_OriginOffset.SetX(-iLength);			break;		case HALIGN_LEFT:		default:			m_OriginOffset.SetX(0);			break;		}		switch (m_eVertAlign)		{		case VALIGN_TOP:			m_OriginOffset.SetY(0);			break;		case VALIGN_BOTTOM:			m_OriginOffset.SetY(iMinY - iMaxY);			break;		case VALIGN_CENTER:			m_OriginOffset.SetY((iMinY - iMaxY) / 2);			break;		case VALIGN_NORMAL:		default:			m_OriginOffset.SetY(-iMaxY);			break;		}		m_bCachedMetricsValid = true;	}	if (pBoundedDimensions)	{		*pBoundedDimensions = m_CachedBoundedDimensions;	}	if (pOriginOffset)	{		*pOriginOffset = m_OriginOffset;	}	if (pCharacterRects)	{		*pCharacterRects = m_CachedCharacterRects;	}}}

⌨️ 快捷键说明

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