- bunnyaruga_demo.zip
- BunnyarugaSetup.exe
- bunnyaruga_src.zip
- Bunnyaruga.sln
- Bunnyaruga
- Configuration
- CustomInstaller
- Deployment
- GXGraphics
- GXInput
- HekkusNet
- Library
- GAPINet
- ARM
- GAPINet.dll
- EULA.rtf
- MIPS
- GAPINet.dll
- SH3
- GAPINet.dll
- Hekkus
- ARMRel
- HekkusSS.dll
- license.txt
- MIPSRel
- HekkusSS.dll
- SH3Rel
- HekkusSS.dll
- Music
- SFX
- blink.wav
- chomp.wav
|
using System;
using System.IO;
using System.Reflection;
using System.Drawing;
namespace GXGraphicsLibrary
{
/// <summary>
/// Encapsulates the functionality of loading and displaying .fnt font
/// data.
/// </summary>
public class GXFont
{
/// <summary>
/// Definition of an unimplemented character. Fonts can implement as few
/// or as many characters as they want. Unsupported characters will be
/// ignored during drawing.
/// </summary>
protected const ushort kUnsupportedCharacter = 0xffff;
/// <summary>
/// The amount of horizontal pixels that a space character ' ' will take up.
/// </summary>
protected int m_spaceWidth;
/// <summary>
/// The amount of vertical pixels to add to a carriage return. This is in
/// addition to the height of the characters, thus resulting in defining the
/// number of pixels between the rows of text.
/// </summary>
protected int m_vertOffset;
/// <summary>
/// The amount of horizontal pixels to add between characters.
/// </summary>
protected int m_horOffset;
/// <summary>
/// The height of this font. All fonts are uniform so all characters are
/// considered the same height.
/// </summary>
public int Height { get { return m_height; } }
protected int m_height;
/// <summary>
/// Number of bytes in a row of pixels embedded in the font file format.
/// </summary>
protected int m_bytesPerRow;
/// <summary>
/// The pixel offset of each text character. If the offset is set to
/// kUnsupportedCharacter then it is not supported by this font. There will
/// be one for each character (256) plus one that is uses to determine the width
/// of the last character for a total of 257.
/// </summary>
protected ushort[] m_xOffset = null;
/// <summary>
/// Image data from the font file. This data is a 1 bit per pixel bitmap.
/// </summary>
protected byte[] m_image = null;
/// <summary>
/// Create a font from a stream that is associated with a .fnt file.
/// </summary>
/// <param name="strm">Stream containing .fnt data</param>
public GXFont(Stream strm)
{
BinaryReader rdr = new BinaryReader(strm);
// Read in the variables stored at the head of the file
m_spaceWidth = rdr.ReadInt32();
m_vertOffset = rdr.ReadInt32();
m_horOffset = rdr.ReadInt32();
m_height = rdr.ReadInt32();
m_bytesPerRow = rdr.ReadInt32();
// There will always be 257 pixel offsets.
m_xOffset = new ushort[257];
// Read in each offset
for (int i = 0; i < 257; i++)
{
m_xOffset[i] = rdr.ReadUInt16();
}
// Allocate space for the 1 bit "bitmap" section of the file and load it
m_image = new byte[rdr.BaseStream.Length - rdr.BaseStream.Position];
m_image = rdr.ReadBytes((int)(rdr.BaseStream.Length - rdr.BaseStream.Position));
}
/// <summary>
/// Draw some text to the specified bitmap.
/// </summary>
/// <param name="gx">Valid GXGraphics object</param>
/// <param name="dstBitmap">Destination GXBitmap of the draw</param>
/// <param name="strText">Text to be displayed</param>
/// <param name="color">Color of text</param>
/// <param name="x">X pixel location to start text</param>
/// <param name="y">Y pixel location to start text</param>
public void DrawString(GXGraphics gx, GXBitmap dstBitmap, string strText, Color color, int x, int y)
{
// Track the x and y pixel offsets of the previously drawn character.
// This is like a cursor.
int prevXOffset = 0;
int prevYOffset = 0;
// Convert the color to the proper pixel format
ushort rgb = gx.PixelConverter.ColorToPixel(color);
// Cache the current draw modes
bool bAlpha = gx.CheckDrawModes(GXGraphics.DrawFlags.kModeAlphaBlending);
bool bSrcKey = gx.CheckDrawModes(GXGraphics.DrawFlags.kModeSrcKeyTransparency);
bool bDstKey = gx.CheckDrawModes(GXGraphics.DrawFlags.kModeDstKeyTransparency);
ushort rSrc = 0;
ushort gSrc = 0;
ushort bSrc = 0;
ushort rDst = 0;
ushort gDst = 0;
ushort bDst = 0;
ushort dAlpha = (ushort)(255 - gx.Alpha);
// If alpha blending is set then initialize the data
if (bAlpha)
{
gx.PixelConverter.PixelToBGR(rgb, ref bSrc, ref gSrc, ref rSrc);
rSrc = (ushort)(gx.Alpha * rSrc);
gSrc = (ushort)(gx.Alpha * gSrc);
bSrc = (ushort)(gx.Alpha * bSrc);
}
// Cache the transparency keys in case they are used
ushort sourceKey = gx.SourceKey;
ushort destinationKey = gx.DestinationKey;
// Loop through each character in the string
for (int i = 0; i < strText.Length; i++)
{
if (strText[i] == ' ')
{
// If the character is a space then move the cursor in the
// x direction
prevXOffset += m_spaceWidth;
}
else if (strText[i] == '\r')
{
// If the character is a carriage return then move the cursor
// in the y direction and set it back to the starting x location
prevYOffset += m_height + m_vertOffset;
prevXOffset = 0;
}
// If this is an unsupported character then skip it
if (m_xOffset[strText[i]] == kUnsupportedCharacter)
continue;
// Find the offset of the next character in the font file
// to determine the extent of the current character
int nextCharIndex = strText[i] + 1;
ushort nextCharXOffset = m_xOffset[nextCharIndex];
while (nextCharXOffset == kUnsupportedCharacter)
{
nextCharXOffset = m_xOffset[nextCharIndex++];
}
int cStart = m_xOffset[strText[i]];
int cEnd = nextCharXOffset;
int xDstPitch = gx.DrawSurface.xPixelPitch;
int yDstPitch = gx.DrawSurface.yPixelPitch;
// Draw the character
unsafe
{
// Set up the starting pixel of the destination draw
ushort* pCurDstLine = (ushort*)dstBitmap.Pixels.ToInt32() + (x + prevXOffset) * xDstPitch + (y + prevYOffset) * yDstPitch;
// Loop through each row of pixels in the font file
for (int r = 0; r < m_height; r++)
{
ushort* pCurDstPixel = pCurDstLine;
if (y + prevYOffset + r >= gx.ScreenHeight)
break;
// Loop through each column of pixels in the current character
for (int c = cStart; c < cEnd; c++)
{
if (x + prevXOffset + cEnd - c >= gx.ScreenWidth)
break;
// The data in the font file is 1 bit so 8 characters are
// packed into a byte. Access the proper byte and determine
// which bit corresponds to the current character
byte curByte = m_image[r * m_bytesPerRow + c / 8];
int curBit = c % 8;
// If the bit that represents this character is set then
// draw the pixel with the desired color.
if ((curByte & (0x80 >> curBit)) != 0)
{
if (!(bSrcKey && rgb == sourceKey) &&
!(bDstKey && *pCurDstPixel == destinationKey))
{
if (bAlpha)
{
gx.PixelConverter.PixelToBGR(*pCurDstPixel, ref bDst, ref gDst, ref rDst);
rDst = (ushort)((rSrc + rDst * dAlpha) >> 8);
gDst = (ushort)((gSrc + gDst * dAlpha) >> 8);
bDst = (ushort)((bSrc + bDst * dAlpha) >> 8);
*pCurDstPixel = gx.PixelConverter.BGRToPixelNoShift((byte)bDst, (byte)gDst, (byte)rDst);
}
else
{
*pCurDstPixel = rgb;
}
}
}
pCurDstPixel += xDstPitch;
}
pCurDstLine += yDstPitch;
}
}
// Increment the current location of the cursor by the width
// of the character and the offset between characters
prevXOffset += cEnd - cStart + m_horOffset;
}
}
/// <summary>
/// Returns the location, width and heigh of the string if it were drawn.
/// </summary>
/// <param name="rExtents">The rectangle encaspulating the text, filled in by this function</param>
/// <param name="strText">The text to be measured</param>
/// <param name="x">The starting x location of the text</param>
/// <param name="y">The starting y location of the text</param>
public void GetTextExtents(ref Rectangle rExtents, string strText, int x, int y)
{
// Set the start location of the draw to the x,y location
rExtents.X = x;
rExtents.Y = y;
// Track the maximum x size of a draw
int maxX = 0;
// Keep track of the cursor location
int prevXOffset = 0;
int prevYOffset = 0;
// Loop through each character in the text
for (int i = 0; i < strText.Length; i++)
{
if (strText[i] == ' ')
{
prevXOffset += m_spaceWidth;
}
else if (strText[i] == '\r')
{
// If a carriage return is detected then check if this is
// the longest line thus far
if (prevXOffset > maxX)
maxX = prevXOffset;
prevYOffset += m_height + m_vertOffset;
prevXOffset = x;
}
if (m_xOffset[strText[i]] == kUnsupportedCharacter)
continue;
int nextCharIndex = strText[i] + 1;
ushort nextCharXOffset = m_xOffset[nextCharIndex];
while (nextCharXOffset == kUnsupportedCharacter)
{
nextCharXOffset = m_xOffset[nextCharIndex++];
}
int cStart = m_xOffset[strText[i]];
int cEnd = nextCharXOffset;
prevXOffset += cEnd - cStart + m_horOffset;
}
if (prevXOffset > maxX)
maxX = prevXOffset;
rExtents.Width = maxX;
rExtents.Height = prevYOffset;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.