#pragma region CPL License /* Nuclex Engine Copyright (C) 2002-2008 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion #include "Nuclex/Text/TextServer.h" #include "Nuclex/Text/FontCodec.h" #include "Nuclex/Support/Exception.h" namespace Nuclex { namespace Text { // ------------------------------------------------------------------------------------------- // namespace { /// Enumerates a list of font codecs class InternalFontCodecEnumerator : public TextServer::CodecEnumerator { /// Map of codecs keyed by their names private: typedef std::map > CodecMap; /// Initializes a new FontCodecEnumerator /// Codecs that will be enumerated by the new enumerator public: InternalFontCodecEnumerator(const CodecMap &Codecs) : m_Codecs(Codecs), m_CodecIt(Codecs.end()), m_CodecEnd(Codecs.end()) {} /// Releases all memory owned by a FontCodecEnumerator public: virtual ~InternalFontCodecEnumerator() {} // // CodecEnumerator implementation // /// Advances to the next entry in the enumeration /// /// True if there was a next entry, false if the end of the enumerator was reached /// public: bool next() { if(m_CodecIt == m_CodecEnd) m_CodecIt = m_Codecs.begin(); else ++m_CodecIt; return (m_CodecIt != m_CodecEnd); } /// Gets the font codec at the enumerator's current position /// The font codec at the enumerator's current position public: const shared_ptr &get() const { return m_CodecIt->second; } /// Map containing the codecs being enumerated /// /// This is an internal implementation that directly references the map of codecs /// from the text server for efficiency and simplicity. /// private: const CodecMap &m_Codecs; /// STL iterator pointing to the enumerator's current codec private: CodecMap::const_iterator m_CodecIt; /// STL iterator pointing to the end of the codec map private: CodecMap::const_iterator m_CodecEnd; }; } // anonymous namespace // ------------------------------------------------------------------------------------------- // namespace { /// Enumerates over a list of fonts class InternalFontEnumerator : public TextServer::FontEnumerator { /// Maps a series of fonts by their names private: typedef std::map > FontMap; /// Initializes a new font enumerator /// Map containing the fonts to enumerate public: InternalFontEnumerator(const FontMap &Fonts) : m_Fonts(Fonts), m_FontIt(Fonts.begin()), m_FontEnd(Fonts.end()) {} /// Releases all memory owned by a font enumerator public: virtual ~InternalFontEnumerator() {} // // FontEnumerator implementation // /// Advance the enumerator to the next entry /// /// True if there was a next entry, false if the end of the enumerator was reached /// public: bool next() { if(m_FontIt == m_FontEnd) m_FontIt = m_Fonts.begin(); else ++m_FontIt; return (m_FontIt != m_FontEnd); } /// Gets the font at the enumerator's current position /// The font at the enumerator's current position const shared_ptr &get() const { return m_FontIt->second; } /// Map containing the fonts being enumerated /// /// This is an internal implementation that directly references the map of fonts /// from the text server for efficiency and simplicity. /// private: const FontMap &m_Fonts; /// STL iterator pointing to the enumerator's current font private: FontMap::const_iterator m_FontIt; /// STL iterator pointing to the end of the font map private: FontMap::const_iterator m_FontEnd; }; } // namespace // ------------------------------------------------------------------------------------------- // const shared_ptr &TextServer::getCodec(const string &sName) const { CodecMap::const_iterator CodecIt = m_Codecs.find(sName); if(CodecIt == m_Codecs.end()) { throw ItemNotFoundException( "Nuclex::Text::TextServer::getCodec()", string("Font codec not found: '") + sName + "'" ); } return CodecIt->second; } // ------------------------------------------------------------------------------------------- // void TextServer::addCodec(const string &sName, const shared_ptr &spCodec) { CodecMap::iterator CodecIt = m_Codecs.find(sName); if(CodecIt != m_Codecs.end()) CodecIt->second = spCodec; else m_Codecs.insert(CodecMap::value_type(sName, spCodec)); } // ------------------------------------------------------------------------------------------- // void TextServer::removeCodec(const string &sName) { CodecMap::iterator CodecIt = m_Codecs.find(sName); if(CodecIt == m_Codecs.end()) { throw ItemNotFoundException( "Nuclex::Text::TextServer::removeCodec()", string("Font codec not found: '") + sName + "'" ); } m_Codecs.erase(CodecIt); } // ------------------------------------------------------------------------------------------- // void TextServer::clearCodecs() { m_Codecs.clear(); } // ------------------------------------------------------------------------------------------- // shared_ptr TextServer::enumCodecs() const { return shared_ptr( new InternalFontCodecEnumerator(m_Codecs) ); } // ------------------------------------------------------------------------------------------- // shared_ptr TextServer::loadFont( const shared_ptr &spSource, const string &sExtension, size_t nSize ) const { CodecMap::const_iterator CodecEnd = m_Codecs.end(); for( CodecMap::const_iterator CodecIt = m_Codecs.begin(); CodecIt != CodecEnd; CodecIt++ ) { if(CodecIt->second->canLoadFont(spSource, sExtension)) { return CodecIt->second->loadFont(spSource, sExtension, nSize); } } throw UnsupportedFontFormatException( "Nuclex::Text::TextServer::loadFont()", "Unsupported font file format" ); } // ------------------------------------------------------------------------------------------- // const shared_ptr &TextServer::getFont(const string &sName) const { FontMap::const_iterator FontIt = m_Fonts.find(sName); if(FontIt == m_Fonts.end()) { throw ItemNotFoundException( "Nuclex::Text::TextServer::getFont()", string("Font not found: '") + sName + "'" ); } return FontIt->second; } // ------------------------------------------------------------------------------------------- // void TextServer::addFont(const string &sName, const shared_ptr &spFont) { FontMap::iterator FontIt = m_Fonts.find(sName); if(FontIt != m_Fonts.end()) FontIt->second = spFont; else m_Fonts.insert(FontMap::value_type(sName, spFont)); } // ------------------------------------------------------------------------------------------- // void TextServer::removeFont(const string &sName) { FontMap::iterator FontIt = m_Fonts.find(sName); if(FontIt == m_Fonts.end()) { throw ItemNotFoundException( "Nuclex::Text::TextServer::removeFont()", string("Font not found: '") + sName + "'" ); } m_Fonts.erase(FontIt); } // ------------------------------------------------------------------------------------------- // void TextServer::clearFonts() { m_Fonts.clear(); } // ------------------------------------------------------------------------------------------- // shared_ptr TextServer::enumFonts() const { return shared_ptr( new InternalFontEnumerator(m_Fonts) ); } // ------------------------------------------------------------------------------------------- // }} // namespace Nuclex::Text