From 677f2605c514fc0c87aa30e790511ba6f170caa7 Mon Sep 17 00:00:00 2001 From: danij Date: Sun, 10 Nov 2013 07:10:11 +0000 Subject: [PATCH] Refactor|Fonts|Client: Completed initial C++ translation of (composite) bitmap fonts Todo: Cleanup. --- doomsday/client/include/resource/bitmapfont.h | 55 ++++---- doomsday/client/include/resource/font.h | 4 - doomsday/client/src/render/rend_font.cpp | 61 ++++---- doomsday/client/src/resource/bitmapfont.cpp | 133 ++++++++---------- doomsday/client/src/resource/fonts.cpp | 27 ++-- 5 files changed, 133 insertions(+), 147 deletions(-) diff --git a/doomsday/client/include/resource/bitmapfont.h b/doomsday/client/include/resource/bitmapfont.h index be66ab8919..353967923e 100644 --- a/doomsday/client/include/resource/bitmapfont.h +++ b/doomsday/client/include/resource/bitmapfont.h @@ -27,15 +27,16 @@ #include #include -// Data for a character. -typedef struct { - RectRaw geometry; - Point2Raw coords[4]; -} bitmapfont_char_t; - class bitmapfont_t : public font_t { public: + // Data for a character. + struct bitmapfont_char_t + { + RectRaw geometry; + Point2Raw coords[4]; + }; + /// Absolute file path to the archived version of this font (if any). ddstring_t _filePath; @@ -48,9 +49,23 @@ class bitmapfont_t : public font_t /// Character map. bitmapfont_char_t _chars[MAX_CHARS]; +public: bitmapfont_t(fontid_t bindId); ~bitmapfont_t(); + static bitmapfont_t *fromFile(fontid_t bindId, char const *resourcePath); + + void rebuildFromFile(char const *resourcePath); + void setFilePath(char const *filePath); + + /// @return GL-texture name. + DGLuint textureGLName() const; + Size2Raw const *textureSize() const; + int textureHeight() const; + int textureWidth() const; + + void charCoords(unsigned char ch, Point2Raw coords[4]); + void glInit(); void glDeinit(); @@ -59,16 +74,6 @@ class bitmapfont_t : public font_t int charHeight(unsigned char ch); }; -void BitmapFont_SetFilePath(font_t *font, char const *filePath); - -/// @return GL-texture name. -DGLuint BitmapFont_GLTextureName(font_t const *font); -Size2Raw const *BitmapFont_TextureSize(font_t const *font); -int BitmapFont_TextureHeight(font_t const *font); -int BitmapFont_TextureWidth(font_t const *font); - -void BitmapFont_CharCoords(font_t *font, unsigned char ch, Point2Raw coords[4]); - class bitmapcompositefont_t : public font_t { public: @@ -106,6 +111,15 @@ class bitmapcompositefont_t : public font_t */ void rebuildFromDef(ded_compositefont_t *def); + patchid_t charPatch(unsigned char ch); + void charSetPatch(unsigned char ch, char const *encodedPatchName); + + de::Texture::Variant *charTexture(unsigned char ch); + + uint8_t charBorder(unsigned char chr); + + void charCoords(unsigned char chr, Point2Raw coords[4]); + void glInit(); void glDeinit(); @@ -114,13 +128,4 @@ class bitmapcompositefont_t : public font_t int charHeight(unsigned char ch); }; -patchid_t BitmapCompositeFont_CharPatch(font_t *font, unsigned char ch); -void BitmapCompositeFont_CharSetPatch(font_t *font, unsigned char ch, char const *encodedPatchName); - -de::Texture::Variant *BitmapCompositeFont_CharTexture(font_t *font, unsigned char ch); - -uint8_t BitmapCompositeFont_CharBorder(font_t *font, unsigned char chr); - -void BitmapCompositeFont_CharCoords(font_t *font, unsigned char chr, Point2Raw coords[4]); - #endif /* LIBDENG_BITMAPFONT_H */ diff --git a/doomsday/client/include/resource/font.h b/doomsday/client/include/resource/font.h index a4d76b6d4d..a97fb5bd21 100644 --- a/doomsday/client/include/resource/font.h +++ b/doomsday/client/include/resource/font.h @@ -101,8 +101,4 @@ class font_t void charSize(Size2Raw *size, unsigned char ch); }; -font_t *Font_FromFile(fontid_t bindId, char const *resourcePath); - -void Font_RebuildFromFile(font_t *font, char const *resourcePath); - #endif // CLIENT_RESOURCE_FONT_H diff --git a/doomsday/client/src/render/rend_font.cpp b/doomsday/client/src/render/rend_font.cpp index 99d527e46b..5467743382 100644 --- a/doomsday/client/src/render/rend_font.cpp +++ b/doomsday/client/src/render/rend_font.cpp @@ -581,20 +581,21 @@ static void textFragmentDrawer(const char* fragment, int x, int y, int alignFlag glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_TEXTURE_2D); } - if(font->type() == FT_BITMAP && 0 != BitmapFont_GLTextureName(font)) + if(bitmapfont_t *bmapFont = font->maybeAs()) { - GL_BindTextureUnmanaged(BitmapFont_GLTextureName(font), gl::ClampToEdge, - gl::ClampToEdge, filterUI? gl::Linear : gl::Nearest); + if(bmapFont->textureGLName()) + { + GL_BindTextureUnmanaged(bmapFont->textureGLName(), gl::ClampToEdge, + gl::ClampToEdge, filterUI? gl::Linear : gl::Nearest); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - glScalef(1.f / BitmapFont_TextureWidth(font), - 1.f / BitmapFont_TextureHeight(font), 1.f); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + glScalef(1.f / bmapFont->textureWidth(), 1.f / bmapFont->textureHeight(), 1.f); + } } - { int pass; - for(pass = (noShadow? 1 : 0); pass < (noCharacter && noGlitter? 1 : 2); ++pass) + for(int pass = (noShadow? 1 : 0); pass < (noCharacter && noGlitter? 1 : 2); ++pass) { count = initialCount; ch = fragment; @@ -731,13 +732,16 @@ static void textFragmentDrawer(const char* fragment, int x, int y, int alignFlag cx += w + sat->tracking; } - }} + } // Restore previous GL-state. - if(font->type() == FT_BITMAP && 0 != BitmapFont_GLTextureName(font)) + if(bitmapfont_t *bmapFont = font->maybeAs()) { - glMatrixMode(GL_TEXTURE); - glPopMatrix(); + if(bmapFont->textureGLName()) + { + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + } } if(renderWireframe > 1) { @@ -767,24 +771,23 @@ static void drawChar(unsigned char ch, int posX, int posY, font_t *font, glMatrixMode(GL_MODELVIEW); glTranslatef(x, y, 0); - switch(font->type()) + if(bitmapfont_t *bmapFont = font->maybeAs()) { - case FT_BITMAP: /// @todo Filtering should be determined at a higher level. /// @todo We should not need to re-bind this texture here. - GL_BindTextureUnmanaged(BitmapFont_GLTextureName(font), gl::ClampToEdge, + GL_BindTextureUnmanaged(bmapFont->textureGLName(), gl::ClampToEdge, gl::ClampToEdge, filterUI? gl::Linear : gl::Nearest); - std::memcpy(&geometry, font->charGeometry(ch), sizeof(geometry)); - BitmapFont_CharCoords(font, ch, coords); - break; - - case FT_BITMAPCOMPOSITE: { - uint8_t const border = BitmapCompositeFont_CharBorder(font, ch); + std::memcpy(&geometry, bmapFont->charGeometry(ch), sizeof(geometry)); + bmapFont->charCoords(ch, coords); + } + else if(bitmapcompositefont_t *compFont = font->maybeAs()) + { + uint8_t const border = compFont->charBorder(ch); - GL_BindTexture(BitmapCompositeFont_CharTexture(font, ch)); + GL_BindTexture(compFont->charTexture(ch)); - std::memcpy(&geometry, font->charGeometry(ch), sizeof(geometry)); + std::memcpy(&geometry, compFont->charGeometry(ch), sizeof(geometry)); if(border) { geometry.origin.x -= border; @@ -792,10 +795,10 @@ static void drawChar(unsigned char ch, int posX, int posY, font_t *font, geometry.size.width += border*2; geometry.size.height += border*2; } - BitmapCompositeFont_CharCoords(font, ch, coords); - break; } - - default: + compFont->charCoords(ch, coords); + } + else + { Con_Error("FR_DrawChar: Invalid font type %i.", (int) font->type()); exit(1); // Unreachable. } diff --git a/doomsday/client/src/resource/bitmapfont.cpp b/doomsday/client/src/resource/bitmapfont.cpp index 00866d5f2f..c25292bffd 100644 --- a/doomsday/client/src/resource/bitmapfont.cpp +++ b/doomsday/client/src/resource/bitmapfont.cpp @@ -133,7 +133,7 @@ static void *readFormat0(font_t *font, de::FileHandle *file) avgSize.width = avgSize.height = 0; for(i = 0; i < glyphCount; ++i) { - bitmapfont_char_t *ch = &bf->_chars[i < MAX_CHARS ? i : MAX_CHARS - 1]; + bitmapfont_t::bitmapfont_char_t *ch = &bf->_chars[i < MAX_CHARS ? i : MAX_CHARS - 1]; ushort x = inShort(file); ushort y = inShort(file); ushort w = inByte(file); @@ -232,7 +232,7 @@ static void *readFormat2(font_t *font, de::FileHandle *file) ushort y = inShort(file); ushort w = inShort(file); ushort h = inShort(file); - bitmapfont_char_t *ch = &bf->_chars[code]; + bitmapfont_t::bitmapfont_char_t *ch = &bf->_chars[code]; ch->geometry.origin.x = 0; ch->geometry.origin.y = 0; @@ -292,28 +292,6 @@ static void *readFormat2(font_t *font, de::FileHandle *file) return image; } -void Font_RebuildFromFile(font_t *font, char const *resourcePath) -{ - if(font->type() != FT_BITMAP) - { - Con_Error("Fonts::RebuildFromFile: Font is of invalid type %i.", int(font->type())); - exit(1); // Unreachable. - } - BitmapFont_SetFilePath(font, resourcePath); -} - -font_t *Font_FromFile(fontid_t bindId, char const *resourcePath) -{ - DENG2_ASSERT(resourcePath != 0); - - bitmapfont_t *font = new bitmapfont_t(bindId); - BitmapFont_SetFilePath(font, resourcePath); - - // Lets try and prepare it right away. - font->glInit(); - return font; -} - bitmapfont_t::bitmapfont_t(fontid_t bindId ) : font_t(FT_BITMAP, bindId) { @@ -329,6 +307,24 @@ bitmapfont_t::~bitmapfont_t() glDeinit(); } +void bitmapfont_t::rebuildFromFile(char const *resourcePath) +{ + setFilePath(resourcePath); +} + +bitmapfont_t *bitmapfont_t::fromFile(fontid_t bindId, char const *resourcePath) // static +{ + DENG2_ASSERT(resourcePath != 0); + + bitmapfont_t *font = new bitmapfont_t(bindId); + font->setFilePath(resourcePath); + + // Lets try and prepare it right away. + font->glInit(); + + return font; +} + RectRaw const *bitmapfont_t::charGeometry(unsigned char chr) { glInit(); @@ -404,67 +400,53 @@ void bitmapfont_t::glDeinit() _tex = 0; } -void BitmapFont_SetFilePath(font_t *font, char const *filePath) +void bitmapfont_t::setFilePath(char const *filePath) { - DENG_ASSERT(font && font->_type == FT_BITMAP); - - bitmapfont_t *bf = (bitmapfont_t *)font; - if(!filePath || !filePath[0]) { - Str_Free(&bf->_filePath); - font->_isDirty = true; + Str_Free(&_filePath); + _isDirty = true; return; } - if(bf->_filePath.size > 0) + if(_filePath.size > 0) { - if(!Str_CompareIgnoreCase(&bf->_filePath, filePath)) + if(!Str_CompareIgnoreCase(&_filePath, filePath)) return; } else { - Str_Init(&bf->_filePath); + Str_Init(&_filePath); } - Str_Set(&bf->_filePath, filePath); - font->_isDirty = true; + Str_Set(&_filePath, filePath); + _isDirty = true; } -DGLuint BitmapFont_GLTextureName(font_t const *font) +DGLuint bitmapfont_t::textureGLName() const { - DENG_ASSERT(font && font->_type == FT_BITMAP); - bitmapfont_t *bf = (bitmapfont_t *)font; - return bf->_tex; + return _tex; } -Size2Raw const *BitmapFont_TextureSize(font_t const *font) +Size2Raw const *bitmapfont_t::textureSize() const { - DENG_ASSERT(font && font->_type == FT_BITMAP); - bitmapfont_t *bf = (bitmapfont_t *)font; - return &bf->_texSize; + return &_texSize; } -int BitmapFont_TextureWidth(font_t const *font) +int bitmapfont_t::textureWidth() const { - DENG_ASSERT(font && font->_type == FT_BITMAP); - bitmapfont_t *bf = (bitmapfont_t *)font; - return bf->_texSize.width; + return _texSize.width; } -int BitmapFont_TextureHeight(font_t const *font) +int bitmapfont_t::textureHeight() const { - DENG_ASSERT(font && font->_type == FT_BITMAP); - bitmapfont_t *bf = (bitmapfont_t *)font; - return bf->_texSize.height; + return _texSize.height; } -void BitmapFont_CharCoords(font_t *font, unsigned char chr, Point2Raw coords[4]) +void bitmapfont_t::charCoords(unsigned char chr, Point2Raw coords[4]) { - DENG_ASSERT(font->_type == FT_BITMAP); - bitmapfont_t *bf = (bitmapfont_t *)font; - bitmapfont_char_t *ch = &bf->_chars[chr]; + bitmapfont_t::bitmapfont_char_t *ch = &_chars[chr]; if(!coords) return; - bf->glInit(); + glInit(); std::memcpy(coords, ch->coords, sizeof(Point2Raw) * 4); } @@ -597,7 +579,7 @@ bitmapcompositefont_t *bitmapcompositefont_t::fromDef(fontid_t bindId, ded_compo try { QByteArray path = reinterpret_cast(*def->charMap[i].path).resolved().toUtf8(); - BitmapCompositeFont_CharSetPatch(font, def->charMap[i].ch, path.constData()); + font->charSetPatch(def->charMap[i].ch, path.constData()); } catch(de::Uri::ResolveError const &er) { @@ -634,7 +616,7 @@ void bitmapcompositefont_t::rebuildFromDef(ded_compositefont_t *def) try { QByteArray path = reinterpret_cast(*def->charMap[i].path).resolved().toUtf8(); - BitmapCompositeFont_CharSetPatch(this, def->charMap[i].ch, path.constData()); + charSetPatch(def->charMap[i].ch, path.constData()); } catch(de::Uri::ResolveError const& er) { @@ -643,42 +625,37 @@ void bitmapcompositefont_t::rebuildFromDef(ded_compositefont_t *def) } } -Texture::Variant *BitmapCompositeFont_CharTexture(font_t *font, unsigned char ch) +Texture::Variant *bitmapcompositefont_t::charTexture(unsigned char ch) { - bitmapcompositefont_t *cf = (bitmapcompositefont_t *)font; - cf->glInit(); - return cf->_chars[ch].tex; + glInit(); + return _chars[ch].tex; } -patchid_t BitmapCompositeFont_CharPatch(font_t *font, unsigned char ch) +patchid_t bitmapcompositefont_t::charPatch(unsigned char ch) { - bitmapcompositefont_t *cf = (bitmapcompositefont_t *)font; - cf->glInit(); - return cf->_chars[ch].patch; + glInit(); + return _chars[ch].patch; } -void BitmapCompositeFont_CharSetPatch(font_t *font, unsigned char chr, char const *encodedPatchName) +void bitmapcompositefont_t::charSetPatch(unsigned char chr, char const *encodedPatchName) { - bitmapcompositefont_t *cf = (bitmapcompositefont_t *)font; - bitmapcompositefont_t::bitmapcompositefont_char_t *ch = &cf->_chars[chr]; + bitmapcompositefont_char_t *ch = &_chars[chr]; ch->patch = R_DeclarePatch(encodedPatchName); - font->_isDirty = true; + _isDirty = true; } -uint8_t BitmapCompositeFont_CharBorder(font_t *font, unsigned char chr) +uint8_t bitmapcompositefont_t::charBorder(unsigned char chr) { - bitmapcompositefont_t *cf = (bitmapcompositefont_t *)font; - bitmapcompositefont_t::bitmapcompositefont_char_t *ch = &cf->_chars[chr]; - cf->glInit(); + bitmapcompositefont_char_t *ch = &_chars[chr]; + glInit(); return ch->border; } -void BitmapCompositeFont_CharCoords(font_t *font, unsigned char /*chr*/, Point2Raw coords[4]) +void bitmapcompositefont_t::charCoords(unsigned char /*chr*/, Point2Raw coords[4]) { - bitmapcompositefont_t *cf = (bitmapcompositefont_t *)font; if(!coords) return; - cf->glInit(); + glInit(); // Top left. coords[0].x = 0; diff --git a/doomsday/client/src/resource/fonts.cpp b/doomsday/client/src/resource/fonts.cpp index 2df35b5c4c..29aa972112 100644 --- a/doomsday/client/src/resource/fonts.cpp +++ b/doomsday/client/src/resource/fonts.cpp @@ -447,8 +447,8 @@ DENG2_PIMPL(Fonts) << self.composeUri(id); #endif compFont->rebuildFromDef(def); - return compFont; } + return record->font; } // A new font. @@ -483,20 +483,22 @@ DENG2_PIMPL(Fonts) if(record->font) { - /// @todo Do not update fonts here (not enough knowledge). We should - /// instead return an invalid reference/signal and force the caller - /// to implement the necessary update logic. - font_t *font = record->font; + if(bitmapfont_t *bmapFont = record->font->maybeAs()) + { + /// @todo Do not update fonts here (not enough knowledge). We should + /// instead return an invalid reference/signal and force the caller + /// to implement the necessary update logic. #ifdef DENG_DEBUG - LOG_DEBUG("A Font with uri \"%s\" already exists, returning existing.") - << self.composeUri(id); + LOG_DEBUG("A Font with uri \"%s\" already exists, returning existing.") + << self.composeUri(id); #endif - Font_RebuildFromFile(font, resourcePath); - return font; + bmapFont->rebuildFromFile(resourcePath); + } + return record->font; } // A new font. - record->font = Font_FromFile(id, resourcePath); + record->font = bitmapfont_t::fromFile(id, resourcePath); if(record->font && verbose >= 1) { LOG_VERBOSE("New font \"%s\"") << self.composeUri(id); @@ -1100,7 +1102,10 @@ font_t *Fonts::createFontFromFile(Uri const &uri, char const *resourcePath) font_t *font = toFont(fontId); if(font) { - Font_RebuildFromFile(font, resourcePath); + if(bitmapfont_t *bmapFont = font->maybeAs()) + { + bmapFont->rebuildFromFile(resourcePath); + } } else {