void BitmapFont::Build() { if (isBuilt) return; if (!LoadFontMap()) { psys->GetLogger("BitmapFont")->Error("Failed to load font map"); return; } for(int i=0; i<256; i++) { if (chardefs[i]->Used()) { BitmapCharDef *character = chardefs[i]; psys->GetLogger("BitmapFont")->Debug("Char '%c' (X:%d, Y:%d), (W:%d, H:%d)",i,character->X(), character->Y(), character->Width(), character->Height()); Bitmap *bmpChar = bitmap->CopyToNew(character->X(), character->Y(), character->Width(), character->Height()); FontChar *fc = new FontChar(i, 0, 0, bmpChar->Width(), bmpChar->Height(), bmpChar); //FontChar *fc = new FontChar(i, 0, 0, bitmap->Width(), bitmap->Height(), bitmap); fc->GenerateTexture(); AddChar(i, fc); } } isBuilt = true; }
FontChar *Font::Draw(int character, float x, float y) { FontChar *c = GetChar(character); if (c != NULL) { c->Draw(x,y,sx,sy); } else { //printf("not found\n"); } return c; }
void Font::Draw(std::string str, float x, float y) { for(int i=0; i<str.length(); i++) { FontChar *c = GetChar(str.at(i)); if (!c) continue; c->Draw(x,y,sx,sy); x+=(c->AdvanceX() >> 6) * sx; y+=(c->AdvanceY() >> 6) * sy; } }
void Font::Estimate(std::string str, float *out_width, float *out_height) { float x,y; x = y = 0; for(int i=0; i<str.length(); i++) { FontChar *c = GetChar(str.at(i)); if (!c) continue; x+=(c->AdvanceX() >> 6) * sx; y+=(c->AdvanceY() >> 6) * sy; } *out_width = x; *out_height = y; }
void BitmapFont::Draw(std::string str, float x, float y) { for(int i=0; i<str.length(); i++) { FontChar *c = GetChar(str.at(i)); if (!c) { continue; } //printf("%c at %f,%f\n",str.at(i),x,y); c->Draw(x,y,sx,sy); x+=c->AdvanceX() * sx; //y+=c->AdvanceY(); } }
void FontLoader::LoadTo(RAM *ram, Font *font) { u16 address = ram->GetFontDataStartAddress(); // TODO: When more fonts will be added, check the size of font space for(u8 charIndex = 0; charIndex < font->GetCharacterCount(); charIndex++) { FontChar *curChar = font->GetCharacterByIndex(charIndex); // TODO: Make rowCount constant in Font. for(u8 rowIndex = 0; rowIndex < curChar->GetRowCount(); rowIndex++) { ram->Write(address + (charIndex * curChar->GetRowCount()) + rowIndex, curChar->GetRow(rowIndex)); } } }
void Font::BuildTexturesForString(std::string &string) { for (int i=0; i<string.length(); i++) { if (FT_Load_Char(face, string.at(i), FT_LOAD_RENDER)) continue; FT_GlyphSlot g = face->glyph; int character = string.at(i); Bitmap *bmp = new Bitmap(g->bitmap.width, g->bitmap.rows, g->bitmap.buffer); FontChar *fc = new FontChar(character, g->bitmap_left, g->bitmap_top, g->advance.x, g->advance.y, bmp); fc->GenerateTexture(); AddChar(character, fc); } }
t_glyph_cache_result add_glyph(FontChar const & font_item, int cacheid, int & cacheidx) { const t_glyph_cache_result ret = priv_add_glyph(font_item, cacheid, cacheidx); if (ret == GLYPH_ADDED_TO_CACHE) { this->glyphs[cacheid][cacheidx].font_item = font_item.clone(); } return ret; }
//============================================================================== bool item_compare(FontChar const & glyph) const noexcept //============================================================================== { return glyph && (this->offset == glyph.offset) && (this->baseline == glyph.baseline) && (this->width == glyph.width) && (this->height == glyph.height) && (0 == memcmp(this->data.get(), glyph.data.get(), glyph.datasize())); }
bool Bitmap::blitString(const char *pszStr, int x, int y, u8 bSize) { // verify valid size index if ( bSize > 3 || !pszStr ) return false; // localize pointer (TODO: get rid of this offset) Font *fnt = BWDATA::FontBase[bSize]; if ( !fnt->isValid() ) return false; // verify if drawing should be done if ( x + fnt->getTextWidth(pszStr) < 0 || y + fnt->getTextHeight(pszStr) < 0 || x >= this->width() || y >= this->height() ) return false; // Reference an unsigned character array const u8 *pbChars = (BYTE*)pszStr; u8 lastColor = 0, color = 0; int Xoffset = x, Yoffset = y; // Iterate all characters in the message for ( int c = 0; pbChars[c]; ++c ) { // Perform control character and whitespace functions if ( pbChars[c] <= ' ' ) { switch ( pbChars[c] ) { case 1: // restore last colour color = lastColor; continue; case '\t': // 9 tab Xoffset += fnt->getCharWidth( pbChars[c] ); continue; case '\n': // 10 newline Xoffset = x; Yoffset += fnt->maxHeight(); continue; case 11: // invisible case 20: color = (BYTE)~0; continue; case '\f': // 12 formfeed break; case '\r': // 13 carriage return case 26: continue; case 18: // right align Xoffset += this->width() - fnt->getTextWidth(pszStr) - x; continue; case 19: // center align Xoffset += (this->width() - fnt->getTextWidth(pszStr))/2 - x; continue; case ' ': // space Xoffset += fnt->maxWidth() / 2; continue; default: // colour code lastColor = color; color = gbColorTable[ pbChars[c] ]; continue; } } // Skip if the character is not supported by the font FontChar *fntChr = fnt->getChar( pbChars[c] ); if ( !fntChr->isValid() ) continue; // If the colour is not "invisible" if ( color != ~0 ) { // begin drawing character process for ( int i = 0, pos = 0; pos < fntChr->height() * fntChr->width(); ++i, ++pos ) { // font position pos += fntChr->pixelOffset(i); // x offset int newX = Xoffset + (fntChr->x() + pos % fntChr->width()); if ( newX >= this->width() ) break; if ( newX < 0 ) continue; // y offset int newY = Yoffset + (fntChr->y() + pos / fntChr->width()); if ( newY >= this->height() ) break; if ( newY < 0 ) continue; // blit offset int offset = newY * this->width() + newX; if ( offset >= this->width() * this->height() ) break; if ( offset < 0 ) continue; // Plot pixel this->data[offset] = gbFontColors[color][fntChr->colorMask(i)]; } } // invis colour // Increment the X offset for the width of the character Xoffset += fntChr->width(); } return true; }
bool Bitmap::blitString(const char *pszStr, int x, int y, u8 size) { // verify valid size index if (size > 3 || !pszStr) return false; // localize pointer Font *fnt = fontBase[size]; if (!fnt) return false; // verify if drawing should be done if (x + fnt->getTextWidth(pszStr) < 0 || y + fnt->getTextHeight(pszStr) < 0 || x >= this->getWidth() || y >= this->getHeight()) return false; // Reference an unsigned character array const u8 *pbChars = (u8*) pszStr; u8 lastColor = 0, color = 0; int Xoffset = x, Yoffset = y; // Iterate all characters in the message for (int c = 0; pbChars[c]; ++c) { // Perform control character and whitespace functions if (pbChars[c] <= ' ') { switch (pbChars[c]) { case 1: // restore last colour color = lastColor; continue; case '\t': // 9 tab Xoffset += fnt->getCharWidth( pbChars[c] ); continue; case '\n': // 10 newline Xoffset = x; Yoffset += fnt->maxHeight(); continue; case 11: // invisible case 20: color = (u8)~0; continue; case '\f': // 12 formfeed break; case '\r': // 13 carriage return case 26: continue; case 18: // right align Xoffset += this->getWidth() - fnt->getTextWidth(pszStr) - x; continue; case 19: // center align Xoffset += (this->getWidth() - fnt->getTextWidth(pszStr))/2 - x; continue; case ' ': // space Xoffset += fnt->maxWidth() / 2; continue; default: // colour code lastColor = color; color = gbColorTable[ pbChars[c] ]; continue; } } //Korean support if (GetUserDefaultLangID() == MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN) && IsDBCSLeadByte(pbChars[c]) && !(pbChars[c] == 169 || pbChars[c] == 153)) { this->blitKoreanChar((char*) &pbChars[c], Xoffset, Yoffset, size, color); if (pbChars[++c]) continue; break; } // Skip if the character is not supported by the font FontChar *fntChr = fnt->getChar( pbChars[c] ); if (!fntChr) continue; // If the colour is not "invisible" if ( color != ~0 ) { // begin drawing character process for ( int i = 0, pos = 0; pos < fntChr->getHeight() * fntChr->getWidth(); ++i, ++pos ) { // font position pos += fntChr->pixelOffset(i); // x offset int newX = Xoffset + (fntChr->getX() + pos % fntChr->getWidth()); if ( newX >= this->getWidth() ) break; if ( newX < 0 ) continue; // y offset int newY = Yoffset + (fntChr->getY() + pos / fntChr->getWidth()); if ( newY >= this->getHeight() ) break; if ( newY < 0 ) continue; // blit offset int offset = newY * this->getWidth() + newX; if ( offset >= this->getWidth() * this->getHeight() ) break; if ( offset < 0 ) continue; // Plot pixel this->data[offset] = gbFontColors[color][fntChr->colorMask(i)]; } } // invis colour // Increment the X offset for the width of the character Xoffset += fntChr->getWidth(); } return true; }
void Font::Bind(int character) { FontChar *c = GetChar(character); if (c != NULL) { c->Bind(); } }