43 #include <boost/unordered_map.hpp>
47 typedef struct FT_FaceRec_* FT_Face;
54 GG_API std::string
RgbaTag(
const Clr& c);
130 typedef std::pair<std::string::const_iterator, std::string::const_iterator> IterPair;
137 std::string::const_iterator first_,
138 std::string::const_iterator second_);
142 Substring(
const std::string& str_,
const IterPair& pair);
145 std::string::const_iterator begin()
const;
148 std::string::const_iterator end()
const;
154 std::size_t size()
const;
157 operator std::string()
const;
160 bool operator==(
const std::string& rhs)
const;
163 bool operator!=(
const std::string& rhs)
const;
168 Substring& operator+=(
const IterPair& rhs);
171 const std::string* str;
172 std::ptrdiff_t first;
173 std::ptrdiff_t second;
175 static const std::string EMPTY_STRING;
204 virtual TextElementType Type()
const;
215 CPSize CodePointSize()
const;
228 mutable X cached_width;
274 const std::vector<boost::shared_ptr<TextElement> >& tags_);
293 std::vector<boost::shared_ptr<FormattingTag> >
tags;
330 Font(
const std::string& font_filename,
unsigned int pts);
336 Font(
const std::string& font_filename,
unsigned int pts,
337 const std::vector<unsigned char>& file_contents);
343 template <
class CharSetIter>
344 Font(
const std::string& font_filename,
unsigned int pts,
345 CharSetIter first, CharSetIter last);
352 template <
class CharSetIter>
353 Font(
const std::string& font_filename,
unsigned int pts,
354 const std::vector<unsigned char>& file_contents,
355 CharSetIter first, CharSetIter last);
362 const std::string& FontName()
const;
366 unsigned int PointSize()
const;
369 const std::vector<UnicodeCharset>& UnicodeCharsets()
const;
385 X SpaceWidth()
const;
390 X RenderGlyph(
const Pt& pt,
char c)
const;
393 X RenderGlyph(
const Pt& pt, boost::uint32_t c)
const;
397 X RenderText(
const Pt& pt,
const std::string& text)
const;
401 const std::vector<LineData>* line_data = 0,
RenderState* render_state = 0)
const;
408 const std::vector<LineData>& line_data,
RenderState& render_state,
409 std::size_t begin_line,
CPSize begin_char,
410 std::size_t end_line,
CPSize end_char)
const;
414 void ProcessTagsBefore(
const std::vector<LineData>& line_data,
RenderState& render_state,
415 std::size_t begin_line,
CPSize begin_char)
const;
420 std::vector<LineData>& line_data)
const;
426 std::vector<LineData>& line_data,
427 std::vector<boost::shared_ptr<TextElement> >& text_elements)
const;
435 const std::vector<boost::shared_ptr<TextElement> >& text_elements,
436 std::vector<LineData>& line_data)
const;
442 X box_width = X0)
const;
445 Pt TextExtent(
const std::string& text,
const std::vector<LineData>& line_data)
const;
451 static void RegisterKnownTag(
const std::string& tag);
455 static void RemoveKnownTag(
const std::string& tag);
459 static void ClearKnownTags();
492 static void ThrowBadGlyph(
const std::string& format_str, boost::uint32_t c);
505 Glyph(
const boost::shared_ptr<Texture>& texture,
const Pt& ul,
const Pt& lr,
Y y_ofs,
515 typedef boost::unordered_map<boost::uint32_t, Glyph> GlyphMap;
517 Pt DetermineLinesImpl(
const std::string& text,
520 std::vector<LineData>& line_data,
521 std::vector<boost::shared_ptr<TextElement> >* text_elements_ptr)
const;
523 FT_Error GetFace(FT_Face& face);
524 FT_Error GetFace(
const std::vector<unsigned char>& file_contents, FT_Face& face);
525 void CheckFace(FT_Face font, FT_Error error);
526 void Init(FT_Face& font);
527 bool GenerateGlyph(FT_Face font, boost::uint32_t ch);
529 inline X RenderGlyph(
const Pt& pt,
const Glyph& glyph,
530 const RenderState* render_state)
const;
531 void HandleTag(
const boost::shared_ptr<FormattingTag>& tag,
double* orig_color,
532 RenderState& render_state)
const;
533 bool IsDefaultFont();
534 boost::shared_ptr<Font>
535 GetDefaultFont(
unsigned int pts);
537 std::string m_font_filename;
538 unsigned int m_pt_sz;
539 std::vector<UnicodeCharset>
545 double m_underline_offset;
546 double m_underline_height;
547 double m_italics_offset;
550 std::vector<boost::shared_ptr<Texture> >
553 static std::set<std::string> s_action_tags;
554 static std::set<std::string> s_known_tags;
558 GG_API std::ostream&
operator<<(std::ostream& os,
const Font::Substring& substr);
565 const std::vector<Font::LineData>& line_data);
572 const std::vector<Font::LineData>& line_data);
578 GG_API std::pair<std::size_t, CPSize>
579 LinePositionOf(CPSize index,
const std::vector<Font::LineData>& line_data);
603 struct GG_API FontKey
605 FontKey(
const std::string& str,
unsigned int pts);
606 bool operator<(
const FontKey& rhs)
const;
608 std::string filename;
616 bool HasFont(
const std::string& font_filename,
unsigned int pts)
const;
620 template <
class CharSetIter>
621 bool HasFont(
const std::string& font_filename,
unsigned int pts,
622 CharSetIter first, CharSetIter last)
const;
629 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts);
634 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
635 const std::vector<unsigned char>& file_contents);
640 template <
class CharSetIter>
641 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
642 CharSetIter first, CharSetIter last);
648 template <
class CharSetIter>
649 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
650 const std::vector<unsigned char>& file_contents,
651 CharSetIter first, CharSetIter last);
655 void FreeFont(
const std::string& font_filename,
unsigned int pts);
660 template <
class CharSetIter>
661 boost::shared_ptr<Font> GetFontImpl(
const std::string& font_filename,
unsigned int pts,
662 const std::vector<unsigned char>* file_contents,
663 CharSetIter first, CharSetIter last);
665 std::map<FontKey, boost::shared_ptr<Font> > m_rendered_fonts;
667 static const boost::shared_ptr<Font> EMPTY_FONT;
679 template <class CharT, bool CharIsSigned = boost::is_signed<CharT>::value>
682 template <
class CharT>
683 struct ValidUTFChar<CharT, true>
685 bool operator()(CharT c)
689 template <
class CharT>
690 struct ValidUTFChar<CharT, false>
692 bool operator()(CharT c)
693 {
return c <= 0x7f; }
696 struct GG_API FTFaceWrapper
708 template <
class CharSetIter>
710 CharSetIter first, CharSetIter last) :
711 m_font_filename(font_filename),
713 m_charsets(first, last),
718 m_underline_offset(0.0),
719 m_underline_height(0.0),
720 m_italics_offset(0.0),
723 if (m_font_filename !=
"") {
724 detail::FTFaceWrapper wrapper;
725 FT_Error error = GetFace(wrapper.m_face);
726 CheckFace(wrapper.m_face, error);
727 Init(wrapper.m_face);
731 template <
class CharSetIter>
733 const std::vector<unsigned char>& file_contents,
734 CharSetIter first, CharSetIter last) :
735 m_font_filename(font_filename),
737 m_charsets(first, last),
742 m_underline_offset(0.0),
743 m_underline_height(0.0),
744 m_italics_offset(0.0),
747 assert(!file_contents.empty());
748 detail::FTFaceWrapper wrapper;
749 FT_Error error = GetFace(file_contents, wrapper.m_face);
750 CheckFace(wrapper.m_face, error);
751 Init(wrapper.m_face);
754 template <
class CharSetIter>
756 CharSetIter first, CharSetIter last)
const
759 FontKey key(font_filename, pts);
760 std::map<FontKey, boost::shared_ptr<Font> >::const_iterator it = m_rendered_fonts.find(key);
761 if (it != m_rendered_fonts.end()) {
762 std::set<UnicodeCharset> requested_charsets(first, last);
763 std::set<UnicodeCharset> found_charsets(it->second->UnicodeCharsets().begin(),
764 it->second->UnicodeCharsets().end());
765 retval = requested_charsets == found_charsets;
770 template <
class CharSetIter>
771 boost::shared_ptr<GG::Font>
773 CharSetIter first, CharSetIter last)
774 {
return GetFontImpl(font_filename, pts, 0, first, last); }
776 template <
class CharSetIter>
777 boost::shared_ptr<GG::Font>
779 const std::vector<unsigned char>& file_contents,
780 CharSetIter first, CharSetIter last)
781 {
return GetFontImpl(font_filename, pts, &file_contents, first, last); }
784 template <
class CharSetIter>
785 boost::shared_ptr<GG::Font>
786 GG::FontManager::GetFontImpl(
const std::string& font_filename,
unsigned int pts,
787 const std::vector<unsigned char>* file_contents,
788 CharSetIter first, CharSetIter last)
790 FontKey key(font_filename, pts);
791 std::map<FontKey, boost::shared_ptr<Font> >::iterator it = m_rendered_fonts.find(key);
792 if (it == m_rendered_fonts.end()) {
793 if (font_filename ==
"") {
798 boost::shared_ptr<Font> font(
800 new Font(font_filename, pts, *file_contents, first, last) :
801 new Font(font_filename, pts, first, last)
803 m_rendered_fonts[key] = font;
804 return m_rendered_fonts[key];
809 std::set<UnicodeCharset> requested_charsets(first, last);
810 std::set<UnicodeCharset> found_charsets(it->second->UnicodeCharsets().begin(),
811 it->second->UnicodeCharsets().end());
812 if (requested_charsets != found_charsets) {
813 std::vector<UnicodeCharset> united_charsets;
814 std::set_union(requested_charsets.begin(), requested_charsets.end(),
815 found_charsets.begin(), found_charsets.end(),
816 std::back_inserter(united_charsets));
817 m_rendered_fonts.erase(it);
818 boost::shared_ptr<Font> font(
820 new Font(font_filename, pts, *file_contents,
821 united_charsets.begin(), united_charsets.end()) :
822 new Font(font_filename, pts,
823 united_charsets.begin(), united_charsets.end())
825 m_rendered_fonts[key] = font;
826 return m_rendered_fonts[key];