#include <objgfx40/ogFont.h> #include <objgfx40/objgfx40.h> extern "C" { #ifdef __UBIXOS_KERNEL__ #include <vfs/file.h> #include <lib/string.h> #else #include <string.h> #include <stdlib.h> #include <stdio.h> #endif } using namespace std; typedef struct { char ID[3]; uInt8 version; uInt8 width, height; uInt8 numOfChars; uInt8 startingChar; uInt8 colourType; uInt8 paddington[7]; } ogDPFHeader; static bool fileExists(const char *file) { #ifdef __UBIXOS_KERNEL__ fileDescriptor *f = fopen(file, "rb"); #else FILE *f = fopen(file, "rb"); #endif if (!f) return false; fclose(f); return true; } ogBitFont::ogBitFont(void) { memset(fontDataIdx, 0, sizeof(fontDataIdx)); memset(charWidthTable, 0, sizeof(charWidthTable)); memset(charHeightTable, 0, sizeof(charHeightTable)); fontData = NULL; fontDataSize = 0; numOfChars = 0; width = height = startingChar = 0; BGColour.red = 0; BGColour.green = 0; BGColour.blue = 0; BGColour.alpha = 0; FGColour.red = 255; FGColour.green = 255; FGColour.blue = 255; FGColour.alpha = 255; return; } // ogBitFont::ogBitFont void ogBitFont::SetBGColor(uInt32 red, uInt32 green, uInt32 blue, uInt32 alpha) { BGColour.red = red; BGColour.green = green; BGColour.blue = blue; BGColour.alpha = alpha; return; } // ogBitFont::SetBGColor void ogBitFont::SetFGColor(uInt32 red, uInt32 green, uInt32 blue, uInt32 alpha) { FGColour.red = red; FGColour.green = green; FGColour.blue = blue; FGColour.alpha = alpha; return; } // ogBitFont::SetFGColor ogBitFont::~ogBitFont(void) { memset(fontDataIdx, 0, sizeof(fontDataIdx)); memset(charWidthTable, 0, sizeof(charWidthTable)); memset(charHeightTable, 0, sizeof(charHeightTable)); delete [] fontData; fontData = NULL; fontDataSize = 0; width = height = startingChar = 0; return; } // ogBitFont::~ogBitFont; void ogBitFont::CenterTextX(ogSurface& dest, int32 y, const char * textString) { int32 x; x = ((dest.ogGetMaxX()+1) - TextWidth(textString)) / 2; PutString(dest, x, y, textString); return; } // ogBitFont::CenterTextX void ogBitFont::JustifyText(ogSurface& dest, ogTextAlign horiz, ogTextAlign vert, const char * textString) { uInt32 x, y; switch (horiz) { case leftText: x = 0; break; case centerText: x = ((dest.ogGetMaxX())-TextWidth(textString)) / 2; break; case rightText: x = (dest.ogGetMaxX())-TextWidth(textString); break; default: return; } // switch switch (vert) { case topText: y = 0; break; case centerText: y = ((dest.ogGetMaxY())-TextHeight(textString)) / 2; break; case bottomText: y = (dest.ogGetMaxY())-TextHeight(textString); default: return; } // switch PutString(dest, x, y, textString); return; } // ogBitFont::JustifyText bool ogBitFont::Load(const char* fontFile, uInt32 offset = 0) { #ifdef __UBIXOS_KERNEL__ fileDescriptor * infile; #else FILE * infile; #endif ogDPFHeader header; uInt32 lresult, size; if (!fileExists(fontFile)) return false; delete [] fontData; infile = fopen(fontFile, "rb"); fseek(infile, offset, SEEK_SET); lresult = fread(&header, sizeof(header), 1, infile); width = header.width; height = header.height; numOfChars = header.numOfChars; if (numOfChars == 0) numOfChars = 256; startingChar = header.startingChar; memset(fontDataIdx, 0, sizeof(fontDataIdx)); memset(charWidthTable, 0, sizeof(charWidthTable)); memset(charHeightTable, 0, sizeof(charHeightTable)); size = (((uInt32)width+7) / 8)*(uInt32)height; fontDataSize = size* (uInt32)numOfChars; for (int32 tmp = startingChar; tmp <= startingChar+numOfChars-1; tmp++) { charWidthTable[tmp] = width; charHeightTable[tmp] = height; fontDataIdx[tmp] = (size*(tmp-startingChar)); } // for tmp fontData = new uInt8[fontDataSize]; lresult = fread(fontData, 1, fontDataSize, infile); fclose(infile); return true; } // ogBitFont::Load /* bool ogFont::LoadFrom(const char* FontFile, uInt32 Offset) { return true; } // ogFont::LoadFrom bool ogFont::Save(const char* FontFile) { return saveTo(FontFile,0); } // ogFont::Save */ uInt32 ogBitFont::TextHeight(const char * textString) { uInt32 size, tmpsize; size = 0; const unsigned char * text = (const unsigned char *)textString; if (text != NULL) while (*text) { tmpsize = charHeightTable[*text++]; if (tmpsize>size) size = tmpsize; } // while return size; } // ogBitFont::TextHeight uInt32 ogBitFont::TextWidth(const char * textString) { uInt32 size = 0; const unsigned char * text = (const unsigned char *)textString; if (text != NULL) while (*text) size += charWidthTable[*text++]; return size; } // ogBitFont::TextWidth /* bool ogBitFont::SaveTo(const char * fontFile, int32 offset) { return true; } // TDPFont::SaveTo */ void ogBitFont::PutChar(ogSurface& dest, int32 x, int32 y, const char ch) { uInt32 xx, xCount, yCount; uInt32 BGC, FGC, tColour; uInt8 * offset; uInt8 bits = 0; const unsigned char c = (const unsigned char)ch; if (fontData == NULL) return; if (!dest.ogAvail()) return; if (charWidthTable[c] != 0) { BGC = dest.ogPack(BGColour.red, BGColour.green, BGColour.blue, BGColour.alpha); BGC &= dest.ogGetAlphaMasker(); tColour = dest.ogGetTransparentColor(); FGC = dest.ogPack(FGColour.red, FGColour.green, FGColour.blue, FGColour.alpha); offset = fontData; offset += fontDataIdx[c]; for (yCount = 0; yCount < height; yCount++) { xCount = charWidthTable[c]; xx = 0; do { if ((xx & 7) == 0) bits = *(offset++); if ((bits & 128) != 0) dest.ogSetPixel(x + xx, y+yCount , FGColour.red, FGColour.green, FGColour.blue, FGColour.alpha); else if (BGC != tColour) dest.ogSetPixel(x + xx, y+yCount, BGC); bits += bits; ++xx; } while (--xCount); } // for yCount } // if return; } // ogBitFont::PutChar void ogBitFont::PutString(ogSurface& dest, int32 x, int32 y, const char *textString) { const unsigned char *text; unsigned char ch; if (textString == NULL) return; if (0 == strlen(textString)) return; if (!dest.ogAvail()) return; text = (const unsigned char *)textString; while ((ch = *text++) != 0) { PutChar(dest, x, y, ch); x += charWidthTable[ch]; } // while return; } // ogBitFont::PutString