From fe030fb6c76354675e3ab91dcf2661bf85ae575b Mon Sep 17 00:00:00 2001 From: Aloshi Date: Wed, 31 Oct 2012 09:46:06 -0500 Subject: [PATCH] Added custom font support. Check out THEMES.md for more information. --- THEMES.md | 22 +++++++++++++++ changelog.txt | 4 +++ src/Font.cpp | 12 +++++++- src/Font.h | 3 ++ src/Renderer_draw_gl.cpp | 7 +++-- src/components/GuiGameList.cpp | 10 +++++-- src/components/GuiList.cpp | 10 +++++-- src/components/GuiList.h | 3 +- src/components/GuiMenu.cpp | 2 +- src/components/GuiTheme.cpp | 50 +++++++++++++++++++++++++++++++--- src/components/GuiTheme.h | 7 ++++- src/main.cpp | 4 +-- 12 files changed, 116 insertions(+), 18 deletions(-) diff --git a/THEMES.md b/THEMES.md index 4d79aa620..62172a284 100644 --- a/THEMES.md +++ b/THEMES.md @@ -114,6 +114,28 @@ Display tags define some "meta" display attributes about your theme. Display tag `` - path to the "top left corner" image file. It will be flipped for the top right, bottom right, and bottom left corners. ~ and . are expanded. + +Fonts +===== + +Fonts are defined like so: + +``` + + ./path/to/font + 0.05 + +``` + +You can leave off any tags you don't want to use, and they'll use the default. Size is defined as a percentage of the screen height. "." and "~" are expanded for paths. + +**Font tags:** + +`` - font to use for the game list. + +`` - font to use for description text. + + Audio ===== diff --git a/changelog.txt b/changelog.txt index d2e74ce7c..fe9ce7ce1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +October 31 +-Added custom font support. Check out THEMES.md. +-Happy halloween! + October 26 -Hopefully fixed the black screen bug with certain programs. diff --git a/src/Font.cpp b/src/Font.cpp index c68acdbfb..70f958b7a 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -10,6 +10,13 @@ bool Font::libraryInitialized = false; int Font::getDpiX() { return 96; } int Font::getDpiY() { return 96; } +int Font::getSize() { return mSize; } + +std::string Font::getDefaultPath() +{ + return "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf"; +} + void Font::initLibrary() { if(FT_Init_FreeType(&sLibrary)) @@ -149,7 +156,10 @@ void Font::buildAtlas() x += g->bitmap.width; } - std::cout << "Final texture coords: " << x << ", " << y << "\n"; + if(y >= textureHeight) + { + std::cerr << "Error - font size exceeded texture size! If you were doing something reasonable, tell Aloshi to fix it!\n"; + } glBindTexture(GL_TEXTURE_2D, 0); diff --git a/src/Font.h b/src/Font.h index af1ad6d5b..f296c0928 100644 --- a/src/Font.h +++ b/src/Font.h @@ -45,6 +45,9 @@ public: void onInit(); void onDeinit(); + int getSize(); + + static std::string getDefaultPath(); private: static int getDpiX(); static int getDpiY(); diff --git a/src/Renderer_draw_gl.cpp b/src/Renderer_draw_gl.cpp index 401b4aaa6..683abfaa3 100644 --- a/src/Renderer_draw_gl.cpp +++ b/src/Renderer_draw_gl.cpp @@ -87,8 +87,9 @@ namespace Renderer { //make sure our font exists if(!boost::filesystem::exists(fontPath)) { - std::cout << "Default font \"" << fontPath << "\" does not exist! Attempting to default to a system font..."; - fontPath = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"; + //std::cout << "Default font \"" << fontPath << "\" does not exist! Attempting to default to a system font..."; + //fontPath = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"; + fontPath = Font::getDefaultPath(); if(!boost::filesystem::exists(fontPath)) { std::cerr << "System font \"" << fontPath << "\" wasn't found either! Well, you're kind of screwed. Sorry.\n"; @@ -96,7 +97,7 @@ namespace Renderer { } } - float fontSizes[] = {0.035, 0.05, 0.1}; + float fontSizes[] = {0.035, 0.045, 0.1}; for(unsigned int i = 0; i < 3; i++) { fonts[i] = new Font(fontPath, (unsigned int)(fontSizes[i] * getScreenHeight())); diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index f47f5d684..8fa6f28f4 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -21,17 +21,18 @@ GuiGameList::GuiGameList(bool useDetail) //Those with smaller displays may prefer the older view. if(mDetailed) { - mList = new GuiList(Renderer::getScreenWidth() * sInfoWidth, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2); + mList = new GuiList(Renderer::getScreenWidth() * sInfoWidth, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM)); mScreenshot = new GuiImage(Renderer::getScreenWidth() * mTheme->getGameImageOffsetX(), Renderer::getScreenHeight() * mTheme->getGameImageOffsetY(), "", Renderer::getScreenWidth() * sInfoWidth * 0.7, 0, false); mScreenshot->setOrigin(mTheme->getGameImageOriginX(), mTheme->getGameImageOriginY()); //addChild(mScreenshot); + //the animation renders the screenshot mImageAnimation = new GuiAnimation(); mImageAnimation->addChild(mScreenshot); addChild(mImageAnimation); }else{ - mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2); + mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM)); mScreenshot = NULL; mImageAnimation = NULL; } @@ -108,7 +109,7 @@ void GuiGameList::onRender() std::string desc = game->getDescription(); if(!desc.empty()) - Renderer::drawWrappedText(desc, Renderer::getScreenWidth() * 0.03, mScreenshot->getOffsetY() + mScreenshot->getHeight() + 12, Renderer::getScreenWidth() * (mTheme->getListOffsetX() - 0.03), mTheme->getDescColor(), Renderer::getDefaultFont(Renderer::SMALL)); + Renderer::drawWrappedText(desc, Renderer::getScreenWidth() * 0.03, mScreenshot->getOffsetY() + mScreenshot->getHeight() + 12, Renderer::getScreenWidth() * (mTheme->getListOffsetX() - 0.03), mTheme->getDescColor(), mTheme->getDescriptionFont()); } } } @@ -226,6 +227,9 @@ void GuiGameList::updateTheme() mList->setSelectedTextColor(mTheme->getSelectedTextColor()); mList->setScrollSound(mTheme->getMenuScrollSound()); + //fonts + mList->setFont(mTheme->getListFont()); + if(mDetailed) { mList->setCentered(mTheme->getListCentered()); diff --git a/src/components/GuiList.cpp b/src/components/GuiList.cpp index 35747aee6..3afedda40 100644 --- a/src/components/GuiList.cpp +++ b/src/components/GuiList.cpp @@ -4,7 +4,7 @@ #include template -GuiList::GuiList(int offsetX, int offsetY, Renderer::FontSize fontsize) +GuiList::GuiList(int offsetX, int offsetY, Font* font) { mSelection = 0; mScrollDir = 0; @@ -16,7 +16,7 @@ GuiList::GuiList(int offsetX, int offsetY, Renderer::FontSize fontsize mTextOffsetX = 0; - mFont = Renderer::getDefaultFont(fontsize); + mFont = font; mSelectorColor = 0x000000FF; mSelectedTextColorOverride = 0x0000FF; mScrollSound = NULL; @@ -266,3 +266,9 @@ void GuiList::setScrollSound(Sound* sound) { mScrollSound = sound; } + +template +void GuiList::setFont(Font* font) +{ + mFont = font; +} diff --git a/src/components/GuiList.h b/src/components/GuiList.h index 0b5e14155..3323aa5bc 100644 --- a/src/components/GuiList.h +++ b/src/components/GuiList.h @@ -15,7 +15,7 @@ template class GuiList : public GuiComponent { public: - GuiList(int offsetX = 0, int offsetY = 0, Renderer::FontSize fontsize = Renderer::MEDIUM); + GuiList(int offsetX, int offsetY, Font* font); ~GuiList(); void onRender(); @@ -44,6 +44,7 @@ public: listType getObject(int i); void setSelection(int i); + void setFont(Font* f); private: static const int SCROLLDELAY = 507; static const int SCROLLTIME = 200; diff --git a/src/components/GuiMenu.cpp b/src/components/GuiMenu.cpp index c62abd294..c3ccee996 100644 --- a/src/components/GuiMenu.cpp +++ b/src/components/GuiMenu.cpp @@ -6,7 +6,7 @@ GuiMenu::GuiMenu(GuiComponent* parent) mParent = parent; parent->pause(); - mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::LARGE); + mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE)); mList->setSelectedTextColor(0x0000FFFF); populateList(); addChild(mList); diff --git a/src/components/GuiTheme.cpp b/src/components/GuiTheme.cpp index aa7d9fd6e..2af0f4e1a 100644 --- a/src/components/GuiTheme.cpp +++ b/src/components/GuiTheme.cpp @@ -36,8 +36,27 @@ float GuiTheme::getGameImageOriginY() { return mGameImageOriginY; } std::string GuiTheme::getImageNotFoundPath() { return mImageNotFoundPath; } +Font* GuiTheme::getListFont() +{ + if(mListFont == NULL) + return Renderer::getDefaultFont(Renderer::MEDIUM); + else + return mListFont; +} + +Font* GuiTheme::getDescriptionFont() +{ + if(mDescFont == NULL) + return Renderer::getDefaultFont(Renderer::SMALL); + else + return mDescFont; +} + GuiTheme::GuiTheme(std::string path) { + mListFont = NULL; + mDescFont = NULL; + setDefaults(); if(!path.empty()) @@ -85,6 +104,18 @@ void GuiTheme::setDefaults() mMenuOpenSound.loadFile(""); mImageNotFoundPath = ""; + + if(mListFont != NULL) + { + delete mListFont; + mListFont = NULL; + } + + if(mDescFont != NULL) + { + delete mDescFont; + mDescFont = NULL; + } } void GuiTheme::deleteComponents() @@ -178,7 +209,8 @@ void GuiTheme::readXML(std::string path) mMenuOpenSound.loadFile(expandPath(root.child("menuOpenSound").text().get())); //fonts - //mListFont = resolveFont(root.child("listFont"), NULL); + mListFont = resolveFont(root.child("listFont"), Font::getDefaultPath(), Renderer::getDefaultFont(Renderer::MEDIUM)->getSize()); + mDescFont = resolveFont(root.child("descriptionFont"), Font::getDefaultPath(), Renderer::getDefaultFont(Renderer::SMALL)->getSize()); //actually read the components createComponentChildren(root, this); @@ -331,13 +363,23 @@ float GuiTheme::strToFloat(std::string str, float defaultVal) return ret; } -Font* GuiTheme::resolveFont(pugi::xml_node node, Font* def) +Font* GuiTheme::resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize) { if(!node) - return def; + return NULL; std::string path = expandPath(node.child("path").text().get()); - int size = (int)(strToFloat(node.child("size").value()) * Renderer::getScreenHeight()); + unsigned int size = (unsigned int)(strToFloat(node.child("size").text().get()) * Renderer::getScreenHeight()); + + if(!boost::filesystem::exists(path)) + { + path = defaultPath; + } + + if(size == 0) + { + size = defaultSize; + } return new Font(path, size); } diff --git a/src/components/GuiTheme.h b/src/components/GuiTheme.h index fd7538875..b1a18bc38 100644 --- a/src/components/GuiTheme.h +++ b/src/components/GuiTheme.h @@ -44,6 +44,9 @@ public: Sound* getMenuOpenSound(); std::string getImageNotFoundPath(); + + Font* getListFont(); + Font* getDescriptionFont(); private: void setDefaults(); void deleteComponents(); @@ -56,7 +59,7 @@ private: unsigned int resolveColor(std::string str, unsigned int defaultColor = 0x000000FF); void splitString(std::string str, char delim, std::string* before, std::string* after); float strToFloat(std::string str, float defaultVal = 0.0f); - Font* resolveFont(pugi::xml_node node, Font* def); + Font* resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize); std::vector mComponentVector; std::string mPath; @@ -67,6 +70,8 @@ private: GuiBoxData mBoxData; Sound mMenuScrollSound, mMenuSelectSound, mMenuBackSound, mMenuOpenSound; std::string mImageNotFoundPath; + Font* mListFont; + Font* mDescFont; }; #endif diff --git a/src/main.cpp b/src/main.cpp index 9639b4aeb..1849d8a15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char* argv[]) }else if(strcmp(argv[i], "--draw-framerate") == 0) { DRAWFRAMERATE = true; - }else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) + }else if(strcmp(argv[i], "--help") == 0) { std::cout << "EmulationStation, a graphical front-end for ROM browsing.\n"; std::cout << "Command line arguments:\n"; @@ -166,7 +166,7 @@ int main(int argc, char* argv[]) ss << framerate; std::string fps; ss >> fps; - Renderer::drawText(fps, 50, 50, 0x00FF00, Renderer::getDefaultFont(Renderer::MEDIUM)); + Renderer::drawText(fps, 50, 50, 0x00FF00FF, Renderer::getDefaultFont(Renderer::MEDIUM)); }