00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #if !defined(_XRB_ASCIIFONT_HPP_)
00012 #define _XRB_ASCIIFONT_HPP_
00013 
00014 #include "xrb.hpp"
00015 
00016 #include <string>
00017 
00018 #include "xrb_font.hpp"
00019 #include "xrb_screencoord.hpp"
00020 
00021 namespace Xrb
00022 {
00023 
00024 class GLTexture;
00025 class RenderContext;
00026 class Serializer;
00027 class Texture;
00028 
00034 class AsciiFont : public Font
00035 {
00036 public:
00037 
00040     virtual ~AsciiFont ()
00041     {
00042         Delete(m_gl_texture);
00043     }
00044 
00045     
00046     
00047     
00048 
00049     enum
00050     {
00051         TAB_SIZE = 4,
00052 
00053         RENDERED_GLYPH_LOWEST = ' ',
00054         RENDERED_GLYPH_HIGHEST = '~',
00055 
00056         RENDERED_GLYPH_COUNT = RENDERED_GLYPH_HIGHEST - RENDERED_GLYPH_LOWEST + 1
00057     };
00058 
00059     struct GlyphSpecification
00060     {
00061         char m_ascii;
00062         ScreenCoordVector2 m_size;
00063         FontCoordVector2 m_bearing_26_6;
00064         FontCoord m_advance_26_6;
00065         ScreenCoordVector2 m_texture_coordinates;
00066 
00067         void Read (Serializer &serializer);
00068         void Write (Serializer &serializer) const;
00069 
00070         static int SortByWidthFirst (
00071             void const *left_operand,
00072             void const *right_operand);
00073         static int SortByHeightFirst (
00074             void const *left_operand,
00075             void const *right_operand);
00076     }; 
00077 
00078     static Uint32 GlyphIndex (char ascii)
00079     {
00080         if (ascii >= RENDERED_GLYPH_LOWEST && ascii <= RENDERED_GLYPH_HIGHEST)
00081             return ascii - RENDERED_GLYPH_LOWEST;
00082         else
00083             return ms_error_glyph - RENDERED_GLYPH_LOWEST;
00084     }
00085     static char AsciiValue (Uint32 glyph_index)
00086     {
00087         if (glyph_index >= RENDERED_GLYPH_COUNT)
00088             return char(ms_error_glyph);
00089         else
00090             return glyph_index + RENDERED_GLYPH_LOWEST;
00091     }
00092 
00102     static AsciiFont *CreateFromCache (
00103         std::string const &font_face_path,
00104         ScreenCoord pixel_height);
00105 
00121     static AsciiFont *Create (
00122         std::string const &font_face_path,
00123         ScreenCoord pixel_height,
00124         bool has_kerning,
00125         ScreenCoord baseline_height,
00126         GlyphSpecification sorted_glyph_specification[RENDERED_GLYPH_COUNT],
00127         FontCoord kern_pair_26_6[RENDERED_GLYPH_COUNT*RENDERED_GLYPH_COUNT],
00128         Texture *font_texture);
00129 
00133     bool CacheToDisk (Texture *font_texture) const;
00134 
00135     
00136     
00137     
00138 
00139     virtual void MoveThroughGlyph (
00140         FontCoordVector2 *pen_position_26_6,
00141         ScreenCoordVector2 const &initial_pen_position,
00142         char const *current_glyph,
00143         char const *next_glyph,
00144         Uint32 *remaining_glyph_count = NULL,
00145         FontCoord *major_space_26_6 = NULL) const;
00146 
00147     virtual void GenerateWordWrappedString (
00148         std::string const &source_string,
00149         std::string *dest_string,
00150         ScreenCoordVector2 const &text_area) const;
00151 
00152 protected:
00153 
00157     AsciiFont (std::string const &font_face_path, ScreenCoord pixel_height)
00158         :
00159         Font(font_face_path, pixel_height)
00160     {
00161         m_gl_texture = NULL;
00162     }
00163 
00164     
00165     
00166     
00167 
00168     virtual void DrawGlyphSetup (RenderContext const &render_context) const;
00169     virtual void DrawGlyphShutdown (RenderContext const &render_context) const;
00170     virtual void DrawGlyph (
00171         RenderContext const &render_context,
00172         char const *glyph,
00173         FontCoordVector2 const &pen_position_26_6) const;
00174 
00175 private:
00176 
00177     
00178     Uint32 Hash () const;
00179     FontCoord KernPair_26_6 (char left, char right) const;
00180 
00181     
00182     
00183     
00184 
00185     enum TokenClass
00186     {
00187         WHITESPACE = 0,
00188         WORD,
00189         NEWLINE,
00190         NULLCHAR
00191     }; 
00192 
00193     static TokenClass GetTokenClass (char const c);
00194     static char const *StartOfNextToken (char const *string);
00195     FontCoord TokenWidth_26_6 (char const *string) const;
00196 
00197     
00198     
00199     
00200 
00201     
00202     static Uint32 const ms_error_glyph = '?';
00203 
00204     
00205     bool m_has_kerning;
00206     
00207     ScreenCoord m_baseline_height;
00208     
00209     GlyphSpecification m_glyph_specification[RENDERED_GLYPH_COUNT];
00210     
00211     FontCoord m_kern_pair_26_6[RENDERED_GLYPH_COUNT*RENDERED_GLYPH_COUNT];
00212     
00213     GLTexture *m_gl_texture;
00214 }; 
00215 
00216 } 
00217 
00218 #endif // !defined(_XRB_ASCIIFONT_HPP_)