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,
514 typedef boost::unordered_map<boost::uint32_t, Glyph> GlyphMap;
516 Pt DetermineLinesImpl(
const std::string& text,
519 std::vector<LineData>& line_data,
520 std::vector<boost::shared_ptr<TextElement> >* text_elements_ptr)
const;
522 FT_Error GetFace(FT_Face& face);
523 FT_Error GetFace(
const std::vector<unsigned char>& file_contents, FT_Face& face);
524 void CheckFace(FT_Face font, FT_Error error);
525 void Init(FT_Face& font);
526 bool GenerateGlyph(FT_Face font, boost::uint32_t ch);
528 inline X RenderGlyph(
const Pt& pt,
const Glyph& glyph,
529 const RenderState* render_state)
const;
530 void HandleTag(
const boost::shared_ptr<FormattingTag>& tag,
double* orig_color,
531 RenderState& render_state)
const;
532 bool IsDefaultFont();
533 boost::shared_ptr<Font>
534 GetDefaultFont(
unsigned int pts);
536 std::string m_font_filename;
537 unsigned int m_pt_sz;
538 std::vector<UnicodeCharset>
544 double m_underline_offset;
545 double m_underline_height;
546 double m_italics_offset;
549 std::vector<boost::shared_ptr<Texture> >
552 static std::set<std::string> s_action_tags;
553 static std::set<std::string> s_known_tags;
557 GG_API std::ostream&
operator<<(std::ostream& os,
const Font::Substring& substr);
564 const std::vector<Font::LineData>& line_data);
571 const std::vector<Font::LineData>& line_data);
577 GG_API std::pair<std::size_t, CPSize>
578 LinePositionOf(CPSize index,
const std::vector<Font::LineData>& line_data);
602 struct GG_API FontKey
604 FontKey(
const std::string& str,
unsigned int pts);
605 bool operator<(
const FontKey& rhs)
const;
607 std::string filename;
615 bool HasFont(
const std::string& font_filename,
unsigned int pts)
const;
619 template <
class CharSetIter>
620 bool HasFont(
const std::string& font_filename,
unsigned int pts,
621 CharSetIter first, CharSetIter last)
const;
628 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts);
633 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
634 const std::vector<unsigned char>& file_contents);
639 template <
class CharSetIter>
640 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
641 CharSetIter first, CharSetIter last);
647 template <
class CharSetIter>
648 boost::shared_ptr<Font> GetFont(
const std::string& font_filename,
unsigned int pts,
649 const std::vector<unsigned char>& file_contents,
650 CharSetIter first, CharSetIter last);
654 void FreeFont(
const std::string& font_filename,
unsigned int pts);
659 template <
class CharSetIter>
660 boost::shared_ptr<Font> GetFontImpl(
const std::string& font_filename,
unsigned int pts,
661 const std::vector<unsigned char>* file_contents,
662 CharSetIter first, CharSetIter last);
664 std::map<FontKey, boost::shared_ptr<Font> > m_rendered_fonts;
666 static const boost::shared_ptr<Font> EMPTY_FONT;
678 template <class CharT, bool CharIsSigned = boost::is_signed<CharT>::value>
681 template <
class CharT>
682 struct ValidUTFChar<CharT, true>
684 bool operator()(CharT c)
688 template <
class CharT>
689 struct ValidUTFChar<CharT, false>
691 bool operator()(CharT c)
692 {
return c <= 0x7f; }
695 struct GG_API FTFaceWrapper
707 template <
class CharSetIter>
709 CharSetIter first, CharSetIter last) :
710 m_font_filename(font_filename),
712 m_charsets(first, last),
717 m_underline_offset(0.0),
718 m_underline_height(0.0),
719 m_italics_offset(0.0),
722 if (m_font_filename !=
"") {
723 detail::FTFaceWrapper wrapper;
724 FT_Error error = GetFace(wrapper.m_face);
725 CheckFace(wrapper.m_face, error);
726 Init(wrapper.m_face);
730 template <
class CharSetIter>
732 const std::vector<unsigned char>& file_contents,
733 CharSetIter first, CharSetIter last) :
734 m_font_filename(font_filename),
736 m_charsets(first, last),
741 m_underline_offset(0.0),
742 m_underline_height(0.0),
743 m_italics_offset(0.0),
746 assert(!file_contents.empty());
747 detail::FTFaceWrapper wrapper;
748 FT_Error error = GetFace(file_contents, wrapper.m_face);
749 CheckFace(wrapper.m_face, error);
750 Init(wrapper.m_face);
753 template <
class CharSetIter>
755 CharSetIter first, CharSetIter last)
const
758 FontKey key(font_filename, pts);
759 std::map<FontKey, boost::shared_ptr<Font> >::const_iterator it = m_rendered_fonts.find(key);
760 if (it != m_rendered_fonts.end()) {
761 std::set<UnicodeCharset> requested_charsets(first, last);
762 std::set<UnicodeCharset> found_charsets(it->second->UnicodeCharsets().begin(),
763 it->second->UnicodeCharsets().end());
764 retval = requested_charsets == found_charsets;
769 template <
class CharSetIter>
770 boost::shared_ptr<GG::Font>
772 CharSetIter first, CharSetIter last)
773 {
return GetFontImpl(font_filename, pts, 0, first, last); }
775 template <
class CharSetIter>
776 boost::shared_ptr<GG::Font>
778 const std::vector<unsigned char>& file_contents,
779 CharSetIter first, CharSetIter last)
780 {
return GetFontImpl(font_filename, pts, &file_contents, first, last); }
783 template <
class CharSetIter>
784 boost::shared_ptr<GG::Font>
785 GG::FontManager::GetFontImpl(
const std::string& font_filename,
unsigned int pts,
786 const std::vector<unsigned char>* file_contents,
787 CharSetIter first, CharSetIter last)
789 FontKey key(font_filename, pts);
790 std::map<FontKey, boost::shared_ptr<Font> >::iterator it = m_rendered_fonts.find(key);
791 if (it == m_rendered_fonts.end()) {
792 if (font_filename ==
"") {
797 boost::shared_ptr<Font> font(
799 new Font(font_filename, pts, *file_contents, first, last) :
800 new Font(font_filename, pts, first, last)
802 m_rendered_fonts[key] = font;
803 return m_rendered_fonts[key];
808 std::set<UnicodeCharset> requested_charsets(first, last);
809 std::set<UnicodeCharset> found_charsets(it->second->UnicodeCharsets().begin(),
810 it->second->UnicodeCharsets().end());
811 if (requested_charsets != found_charsets) {
812 std::vector<UnicodeCharset> united_charsets;
813 std::set_union(requested_charsets.begin(), requested_charsets.end(),
814 found_charsets.begin(), found_charsets.end(),
815 std::back_inserter(united_charsets));
816 m_rendered_fonts.erase(it);
817 boost::shared_ptr<Font> font(
819 new Font(font_filename, pts, *file_contents,
820 united_charsets.begin(), united_charsets.end()) :
821 new Font(font_filename, pts,
822 united_charsets.begin(), united_charsets.end())
824 m_rendered_fonts[key] = font;
825 return m_rendered_fonts[key];