/// <summary> /// Pack a single character so that each pixel is represented by a single bit. /// </summary> /// <param name="character">Character to pack.</param> /// <returns>The packed character.</returns> private CharacterBitmap PackCharacter(CharacterBitmap character) { CharacterBitmap packedCharacter = new CharacterBitmap(); int packedValue = 0; int bits = 16; packedCharacter.Offset = character.Offset; packedCharacter.Width = character.Width; // Loop through all pixels, condensing them into single bits for (int y = 0; y < mFont.Height; ++y) { for (int x = 0; x < character.Width; ++x) { // Set bit if pixel is not transparent if (character.Data[x + (y * mFont.Width)] != 0) { packedValue += (1 << (bits - 1)); } bits--; // Append packed value to data if processed 16 bits if (bits == 0) { packedCharacter.Data.Add(packedValue); bits = 16; packedValue = 0; } } } // Add any trailing bits as a new value if ((bits != 16) || (character.Width == 0)) { packedCharacter.Data.Add(packedValue); } return(packedCharacter); }
/// <summary> /// Builds an array of converted glyphs from the source bitmap. /// </summary> protected void BuildCharacterData() { // Variables for loop int charX = 0; int charY = 0; bool gotData = false; CharacterBitmap character = null; Color col; // Width of space is 1/4th height of font, rounded up mSpaceWidth = (mFont.Height + 3) / 4; // Loop through all characters in the font for (int i = 0; i < 256; ++i) { // Create a new character object to store this character character = new CharacterBitmap(); character.Width = 0; character.CharTop = 0; gotData = false; // Loop through all pixels in this character's bitmap for (int y = 0; y < mFont.Height; ++y) { for (int x = 0; x < mFont.Width; ++x) { // Store the pixel in the character object in 16-bit RGBA 1555 format col = mBitmap.GetPixel(x + charX, y + charY); // Did we find any data in this character? if (!col.Equals(mBackgroundColour)) { // Add the colour to the character's bitmap character.Data.Add(ColorToRGBA16(col)); gotData = true; // Update the width of this character if (x + 1 > character.Width) { character.Width = x + 1; // Is this the largest width yet seen? if (character.Width > mMaximumObservedWidth) { mMaximumObservedWidth = character.Width; } } // Update the chartop of this character if (y > character.CharTop) { character.CharTop = y; } } else { // No data; add 0 to the character's bitmap character.Data.Add(0); } } } // Remember the chartop if this is the "a" character if (i == 'a') { mFont.CharTop = character.CharTop; } // Add the character to the character array mCharacters.Add(character); // Move to the next character in the bitmap charX += mFont.Width; // Wrap to the next row of characters if we've moved past the end // of the bitmap if (charX >= mBitmap.Width) { charX = 0; charY += mFont.Height; } // If we found data and this is the first character to contain data, remember this character if ((mFirstChar < 0) && (gotData)) { mFirstChar = i; } // If we found data, this is the last character so far to contain it if (gotData) { mLastChar = i; } } // Ensure we have a valid chartop - use the font height if we don't have one. // This can only arise if there is no 'a' in the font if (mFont.CharTop == 0) { mFont.CharTop = mFont.Height; } }
/// <summary> /// Appends the glyph data to the .cpp output string. /// </summary> private void AppendGlyphs() { CharacterBitmap character = null; // Calculate the number of shorts in the data int shortCount = GetShortCount(); mOutputCPP.Append(String.Format("static const u16 {0}_glyphdata[{1}] = ", mFont.ClassName, shortCount)); mOutputCPP.Append("{\n"); // Append glyph data int pos = 0; for (int i = mFirstChar; i <= mLastChar; ++i) { character = mCharacters[i]; character.Offset = pos; if (mIsMonochrome) { // Append the character itself mOutputCPP.Append(String.Format("/* {0} */\t", PrintableChar((char)i))); // Append all pixels foreach (int value in character.Data) { // Append a hex-formatted version of the data mOutputCPP.Append(String.Format("{0},", IntToHexString(value))); pos++; } } else { // Append the character itself mOutputCPP.Append(String.Format("\t// {0}\n", PrintableChar((char)i))); // Append all pixels for (int y = 0; y < mFont.Height; ++y) { for (int x = 0; x < character.Width; ++x) { // Append a hex-formatted version of the data mOutputCPP.Append(String.Format("\t{0},", IntToHexString(character.Data[x + (y * mFont.Width)]))); pos++; } // Line break at the end of the row mOutputCPP.Append("\n"); } } // Line break between chars mOutputCPP.Append("\n"); } // Append closing bracket mOutputCPP.Append("};\n\n"); }