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

📄 font.cpp

📁 这个是symbian下的一个蛮庞大的3D游戏源代码!对于学习3D开发的人有很大的帮助!
💻 CPP
字号:
#include "Font.h"
#include "Context.h"
#include "dprintf.h"
#include <lang/Globals.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <config.h>


const int CHAR_X_SPACE = 0;


Font::Font() :
	m_loaded( false )
{
}

Font::~Font()
{
	m_img.destroy();
}

void Font::load( const char* fname, int w, int h )
{
	// Source data pattern: 16 x 16 characters
	dprintf( "Font::load: m_img.loadCustom( %s )\n", fname );
	m_img.loadCustom( fname );
	m_fontBaseWidth = w;
	m_fontHeight = h;
	process();
	m_loaded = true;
}

void Font::process()
{
	uint16_t* data = (uint16_t*) m_img.data();
	uint16_t* markerLine = 0;
	const int yBaseStep = ( m_img.pitch() >> 1 ) * m_fontHeight;

	// get the marker color from the second pixel (the first pixel is the transparency color key)
	uint16_t markerColor = data[1];

	// Source data pattern: 16 x 16 characters
	// Calculate character coordinates (x and y) and widths
	// based on marker pixels in the surface
	// while making marker pixels invisible
	bool charProcessed = false;
	bool widthCountingActive = false;
	int charWidth = 0;
	int xCoord = 0;
	int yCoord = 0;
	int yBase = 0;
	int ch = 0;
	for ( int y = 0; y < 16; y++ )
	{
		xCoord = 0;
		for ( int x = 0; x < 16; x++ )
		{
			if ( ch == 0 )
			{
				//Empty character
				m_charX[ch] = 0;
				m_charY[ch] = 0;
				m_charWidth[ch++] = 0;
				xCoord += m_fontBaseWidth;
				continue;
			}

			m_charX[ch] = xCoord; // store initial character x coordinate
			m_charY[ch] = yCoord; // store character y coordinate
			markerLine = &data[ yBase + xCoord ];
			charProcessed = false;
			widthCountingActive = false;
			charWidth = 0;

			// check character
			for ( int i = 0; i < m_fontBaseWidth; i++ )
			{
				if ( markerLine[i] == markerColor )
				{
					// marker pixel
					if ( !charProcessed && !widthCountingActive )
					{
						// start of marker pixel line
						m_charX[ch] += i;			// update x coordinate
						widthCountingActive = true;	// activate width counting
					}
					markerLine[i] &= 0x0FFF; // make the pixel invisible
				}
				else
				{
					// not marker pixel
					if ( !charProcessed && widthCountingActive )
					{
						// end of marker pixel line
						widthCountingActive = false;	// inactivate width counting
						charProcessed = true;			// and mark the character processed
					}
				}
				if ( widthCountingActive ) charWidth++; // update character width
			}
			m_charWidth[ch++] = charWidth; // store character width
			xCoord += m_fontBaseWidth;
		}
		yBase += yBaseStep;
		yCoord += m_fontHeight;
	}
}

void Font::drawText( Context* context, int x, int y, int* outx, int* outy, const char* fmt, ... )
{
	if ( !m_loaded ) return;

	// format variable arguments
	const unsigned MAX_MSG = 500;
	char msg[MAX_MSG+4];
	va_list marker;
	va_start( marker, fmt );
	vsprintf( msg, fmt, marker );
	va_end( marker );
	unsigned int len = strlen(msg);
	assert( len < MAX_MSG ); // too long debug message

	uint8_t* buffer = (uint8_t*)context->buffer();
	int pitch = context->pitch();
	int width = context->width();
	int height = context->height();
	Surface dst( buffer, pitch, width, height );

	int rowx = x;
	char ch = 0;
	for ( int i = 0 ; i < (int)len ; ++i )
	{
		ch = msg[i];
		if ( ch == 0 ) break;
		if ( ch == '\n' )
		{
			x = rowx;
			y += m_fontHeight;
			continue;
		}

		int x0 = m_charX[ch];
		int y0 = m_charY[ch];

		int charWidth = m_charWidth[ch];
		int x1 = x0 + charWidth;
		if ( x1 > m_img.width() ) x1 = m_img.width();
		Surface sf = m_img.clip( x0, y0, x1, y0 + m_fontHeight );

		dst.blt( x, y, sf, Surface::BLEND_ALPHA1B );
		x += charWidth + CHAR_X_SPACE;
	}
	y += m_fontHeight;

	if ( outx )
		*outx = x;
	if ( outy )
		*outy = y;
}

int	Font::getTextWidth( const char* msg, int* outLines, int* outHeight ) const
{
	if ( !m_loaded ) return 0;

	int maxWidth = 0;
	int lineWidth = 0;
	int lines = 0;
	char ch = 0;
	for ( int i = 0; msg[i]; ++i )
	{
		ch = msg[i];
		if ( ch != '\n' )
		{
			lineWidth += m_charWidth[ch] + CHAR_X_SPACE;
		}
		if ( ch == '\n' || msg[i + 1] == 0 )
		{
			if ( lineWidth > maxWidth ) maxWidth = lineWidth;
			lineWidth = 0;
			++lines;
		}
	}

	if ( outLines ) *outLines = lines;
	if ( outHeight ) *outHeight = lines * m_fontHeight;

	return maxWidth;
}

int Font::fontHeight() const
{
	if ( !m_loaded ) return 0;

	return m_fontHeight;
}

// End of file

⌨️ 快捷键说明

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