Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

gltext.h

00001 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil c-basic-offset: 3 -*- */
00002 // vim:cindent:ts=3:sw=3:et:tw=80:sta:
00003 /*************************************************************** gltext-cpr beg
00004  *
00005  * GLText - OpenGL TrueType Font Renderer
00006  * GLText is (C) Copyright 2002 by Ben Scott
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Library General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Library General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Library General Public
00019  * License along with this library; if not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00021  * Boston, MA 02111-1307, USA.
00022  *
00023  * -----------------------------------------------------------------
00024  * File:          $RCSfile: gltext.h,v $
00025  * Date modified: $Date: 2003/06/03 22:21:23 $
00026  * Version:       $Revision: 1.25 $
00027  * -----------------------------------------------------------------
00028  *
00029  ************************************************************ gltext-cpr-end */
00030 #ifndef GLTEXT_H
00031 #define GLTEXT_H
00032 
00033 #ifndef __cplusplus
00034 #  error GLText requires C++
00035 #endif
00036 
00037 #include <sstream>
00038 
00039 // The calling convention for cross-DLL calls in win32
00040 #ifndef GLTEXT_CALL
00041 #  ifdef WIN32
00042 #    define GLTEXT_CALL __stdcall
00043 #  else
00044 #    define GLTEXT_CALL
00045 #  endif
00046 #endif
00047 
00048 // Export functions from the DLL
00049 #ifndef GLTEXT_DECL
00050 #  if defined(WIN32) || defined(_WIN32)
00051 #    ifdef GLTEXT_EXPORTS
00052 #      define GLTEXT_DECL __declspec(dllexport)
00053 #    else
00054 #      define GLTEXT_DECL __declspec(dllimport)
00055 #    endif
00056 #  else
00057 #    define GLTEXT_DECL
00058 #  endif
00059 #endif
00060 
00061 #define GLTEXT_FUNC(ret) extern "C" GLTEXT_DECL ret GLTEXT_CALL
00062 
00063 namespace gltext
00064 {
00065    typedef unsigned char u8;
00066 
00067 
00068    /**
00069     * Base class for classes the manage their own memory using reference
00070     * counting.
00071     *
00072     * This class was originally written by Chad Austin for the audiere project
00073     * and released under the LGPL.
00074     */
00075    class RefCounted
00076    {
00077    protected:
00078       /**
00079        * Protected so users of recounted classes don't use std::auto_ptr or the
00080        * delete operator.
00081        *
00082        * Interfaces that derive from RefCounted should define an inline, empty,
00083        * protected destructor as well.
00084        */
00085       ~RefCounted() {}
00086 
00087    public:
00088       /**
00089        * Add a reference to this object. This will increment the internal
00090        * reference count.
00091        */
00092       virtual void GLTEXT_CALL ref() = 0;
00093 
00094       /**
00095        * Remove a reference from this object. This will decrement the internal
00096        * reference count. When this count reaches 0, the object is destroyed.
00097        */
00098       virtual void GLTEXT_CALL unref() = 0;
00099    };
00100 
00101    /**
00102     * This defines a smart pointer to some type T that implements the RefCounted
00103     * interface. This object will do all the nasty reference counting for you.
00104     *
00105     * This class was originally written by Chad Austin for the audiere project
00106     * and released under the LGPL.
00107     */
00108    template< typename T >
00109    class RefPtr
00110    {
00111    public:
00112       RefPtr(T* ptr = 0)
00113       {
00114          mPtr = 0;
00115          *this = ptr;
00116       }
00117 
00118       RefPtr(const RefPtr<T>& ptr)
00119       {
00120          mPtr = 0;
00121          *this = ptr;
00122       }
00123 
00124       ~RefPtr()
00125       {
00126          if (mPtr)
00127          {
00128             mPtr->unref();
00129             mPtr = 0;
00130          }
00131       }
00132 
00133       RefPtr<T>& operator=(T* ptr)
00134       {
00135          if (ptr != mPtr)
00136          {
00137             if (mPtr)
00138             {
00139                mPtr->unref();
00140             }
00141             mPtr = ptr;
00142             if (mPtr)
00143             {
00144                mPtr->ref();
00145             }
00146          }
00147          return *this;
00148       }
00149 
00150       RefPtr<T>& operator=(const RefPtr<T>& ptr)
00151       {
00152          *this = ptr.mPtr;
00153          return *this;
00154       }
00155 
00156       T* operator->() const
00157       {
00158          return mPtr;
00159       }
00160 
00161       T& operator*() const
00162       {
00163          return *mPtr;
00164       }
00165 
00166       operator bool() const
00167       {
00168          return (mPtr != 0);
00169       }
00170 
00171       T* get() const
00172       {
00173          return mPtr;
00174       }
00175 
00176    private:
00177       T* mPtr;
00178    };
00179 
00180 
00181    /**
00182     * A basic implementation of the RefCounted interface.  Derive your
00183     * implementations from RefImpl<YourInterface>.
00184     *
00185     * This class was originally written by Chad Austin for the audiere project
00186     * and released under the LGPL.
00187     */
00188    template< class Interface >
00189    class RefImpl : public Interface
00190    {
00191    protected:
00192       RefImpl()
00193          : mRefCount(0)
00194       {}
00195 
00196       /**
00197        * So the implementation can put its destruction logic in the destructor,
00198        * as natural C++ code does.
00199        */
00200       virtual ~RefImpl() {}
00201 
00202    public:
00203       void GLTEXT_CALL ref()
00204       {
00205          ++mRefCount;
00206       }
00207 
00208       void GLTEXT_CALL unref()
00209       {
00210          if (--mRefCount == 0)
00211          {
00212             delete this;
00213          }
00214       }
00215 
00216    private:
00217       int mRefCount;
00218    };
00219 
00220 
00221    /// Renderer types supported
00222    enum FontRendererType
00223    {
00224       BITMAP,
00225       PIXMAP,
00226       TEXTURE,
00227       MIPMAP,
00228    };
00229 
00230 
00231    /// Represents a particular shape in a font used to represent one
00232    /// or more characters.
00233    class Glyph : public RefCounted
00234    {
00235    protected:
00236       ~Glyph() {}
00237 
00238    public:
00239       /// Returns width in pixels
00240       virtual int GLTEXT_CALL getWidth() = 0;
00241 
00242       /// Returns height in pixels.
00243       virtual int GLTEXT_CALL getHeight() = 0;
00244       
00245       /// Returns the X offset of this glyph when it is drawn.
00246       virtual int GLTEXT_CALL getXOffset() = 0;
00247       
00248       /// Returns the Y offset of this glyph when it is drawn.
00249       virtual int GLTEXT_CALL getYOffset() = 0;
00250 
00251       /// Returns the number of pixels the pen should move to the
00252       /// right to draw the next character
00253       virtual int GLTEXT_CALL getAdvance() = 0;
00254 
00255       /// Renders the glyph into a buffer of width * height bytes.  A
00256       /// value of 0 means the pixel is transparent; likewise, 255
00257       /// means opaque.
00258       virtual void GLTEXT_CALL render(u8* pixels) = 0;
00259 
00260       /// renderBitmap() is the same as render, except that it only
00261       /// uses values 0 and 255.  These bitmaps may look better on
00262       /// two-color displays.
00263       virtual void GLTEXT_CALL renderBitmap(u8* pixels) = 0;
00264    };
00265 
00266 
00267    /**
00268     * Represents a particular font face.
00269     */
00270    class Font : public RefCounted
00271    {
00272    protected:
00273       ~Font() {}
00274 
00275    public:
00276       /// Gets the name of this font.
00277       virtual const char* GLTEXT_CALL getName() = 0;
00278 
00279       /**
00280        * Returns the glyph object associated with the character c in
00281        * the font.
00282        */
00283       virtual Glyph* GLTEXT_CALL getGlyph(unsigned char c) = 0;
00284 
00285       /// Gets the point size of this font.
00286       virtual int GLTEXT_CALL getSize() = 0;
00287 
00288       /**
00289        * Returns the DPI value passed to OpenFont() when this font
00290        * was created.
00291        */
00292       virtual int GLTEXT_CALL getDPI() = 0;
00293 
00294       /**
00295        * Gets the ascent of this font. This is the distance from the
00296        * baseline to the top of the tallest glyph of this font.
00297        */
00298       virtual int GLTEXT_CALL getAscent() = 0;
00299 
00300       /**
00301        * Gets the descent of this font. This is the distance from the
00302        * baseline to the bottom of the glyph that descends the most
00303        * from the baseline.
00304        */
00305       virtual int GLTEXT_CALL getDescent() = 0;
00306 
00307       /**
00308        * Gets the distance that must be placed between two lines of
00309        * text. Thus the baseline to baseline distance can be computed
00310        * as ascent + descent + linegap.
00311        */
00312       virtual int GLTEXT_CALL getLineGap() = 0;
00313 
00314       /**
00315        * Returns the kerning distance between character c1 and
00316        * character c2.  The kerning distance is added to the previous
00317        * character's advance distance.
00318        */
00319       virtual int GLTEXT_CALL getKerning(unsigned char l, unsigned char r) = 0;
00320    };
00321    typedef RefPtr<Font> FontPtr;
00322 
00323 
00324    /**
00325     * Interface to an object that knows how to render a font.
00326     */
00327    class FontRenderer : public RefCounted
00328    {
00329    protected:
00330       ~FontRenderer() {}
00331 
00332    public:
00333       /**
00334        * Renders the text in the given string as glyphs using this font
00335        * renderer's current font.
00336        */
00337       virtual void GLTEXT_CALL render(const char* text) = 0;
00338 
00339       /**
00340        * Computes the width of the given text string if it were to be rendered
00341        * with this renderer.
00342        */
00343       virtual int GLTEXT_CALL getWidth(const char* text) = 0;
00344 
00345       /**
00346        * Computes the height of the given text string if it were to be
00347        * rendered with this renderer.
00348        */
00349       virtual int GLTEXT_CALL getHeight(const char* text) = 0;
00350 
00351       /**
00352        * Returns the font used to create this renderer.
00353        */
00354       virtual Font* GLTEXT_CALL getFont() = 0;
00355    };
00356    typedef RefPtr<FontRenderer> FontRendererPtr;
00357 
00358 
00359    /**
00360     * Provides an iostream-like interface to a font renderer.  Use as follows:
00361     * Stream(renderer).get() << blah blah blah;
00362     *
00363     * The GLTEXT_STREAM macro may be simpler:
00364     * GLTEXT_STREAM(renderer) << blah blah blah;
00365     */
00366    class Stream : public std::ostringstream
00367    {
00368    public:
00369       Stream(FontRenderer* r)
00370          : mRenderer(r)
00371       {
00372       }
00373       
00374       Stream(const FontRendererPtr& p)
00375          : mRenderer(p.get())
00376       {
00377       }
00378 
00379       ~Stream()
00380       {
00381          flush();
00382       }
00383 
00384       /**
00385        * This is a little trick to convert an rvalue to an lvalue.
00386        * The problem is this: class temporaries created with
00387        * FontStream(r) are rvalues, which means they cannot be
00388        * assigned to FontStream& references.  Therefore, temporaries
00389        * cannot be used as arguments to the standard operator<<
00390        * overloads.
00391        *
00392        * However!  You CAN call methods on object rvalues and methods
00393        * CAN return lvalues!  This method effectively converts *this
00394        * from an rvalue to an lvalue using the syntax:
00395        * FontStream(r).get().
00396        */
00397       Stream& get()
00398       {
00399          return *this;
00400       }
00401 
00402       FontRenderer* getRenderer()
00403       {
00404          return mRenderer.get();
00405       }
00406 
00407       /**
00408        * Calls render() on the associated FontRenderer using the
00409        * string that has been created so far.  Then it sets the string
00410        * to empty.  flush() is called before any GLText manipulator
00411        * and when the font stream is destroyed.
00412        */
00413       void flush()
00414       {
00415          mRenderer->render(str().c_str());
00416          str("");
00417       }
00418 
00419    private:
00420       FontRendererPtr mRenderer;
00421    };
00422 
00423    /**
00424     * This generic insertion operator can take any type (but fails if
00425     * the type can't be inserted into a std::ostream) and returns a
00426     * FontStream&.  Otherwise, something like |FontStream(...) <<
00427     * "blah" << gltextmanip;| would not work, as 'gltextmanip' cannot
00428     * be inserted into a std::ostream.
00429     */
00430    template<typename T>
00431    Stream& operator<<(Stream& fs, T t)
00432    {
00433       static_cast<std::ostream&>(fs) << t;
00434       return fs;
00435    }
00436 
00437    /**
00438     * Flush the font stream and apply the gltext stream manipulator to it.
00439     */
00440    inline Stream& operator<<(Stream& fs, Stream& (*manip)(Stream&))
00441    {
00442       fs.flush();
00443       return manip(fs);
00444    }
00445 
00446    /**
00447     * A convenience macro around gltext::Stream().  Used as follows:
00448     * GLTEXT_STREAM(renderer) << blah blah blah;
00449     *
00450     * This is the preferred interface for streaming text to a
00451     * renderer.
00452     */
00453    #define GLTEXT_STREAM(renderer) gltext::Stream(renderer).get()
00454 
00455 
00456    /**
00457     * PRIVATE API - for internal use only
00458     * Anonymous namespace containing our exported functions. They are extern "C"
00459     * so we don't mangle the names and they export nicely as shared libraries.
00460     */
00461    namespace internal
00462    {
00463       /// Gets version information
00464       GLTEXT_FUNC(const char*) GLTextGetVersion();
00465 
00466       /// Creates a new Font by name.
00467       GLTEXT_FUNC(Font*) GLTextOpenFont(const char* name, int size, int dpi);
00468 
00469       /// Creates a new FontRenderer.
00470       GLTEXT_FUNC(FontRenderer*) GLTextCreateRenderer(
00471          FontRendererType type,
00472          Font* font);
00473    }
00474 
00475    /**
00476     * Gets the version string for GLText.
00477     *
00478     * @return  GLText version information
00479     */
00480    inline const char* GetVersion()
00481    {
00482       return internal::GLTextGetVersion();
00483    }
00484 
00485    /**
00486     * Creates a new font from the given name, style and point size.
00487     *
00488     * @param name    the name of a particular font face.
00489     * @param size    the point size of the font, in 1/72nds of an inch.
00490     * @param dpi     number of pixels per inch on the display
00491     */
00492    inline Font* OpenFont(const char* name, int size, int dpi = 72)
00493    {
00494       return internal::GLTextOpenFont(name, size, dpi);
00495    }
00496 
00497    /**
00498     * Creates a new font renderer of the given type.
00499     *
00500     * @param type    the type of renderer to create.
00501     * @param font    the font to render
00502     */
00503    inline FontRenderer* CreateRenderer(FontRendererType type,
00504                                        const FontPtr& font)
00505    {
00506       return internal::GLTextCreateRenderer(type, font.get());
00507    }
00508 }
00509 
00510 
00511 #endif

Generated on Mon Aug 4 22:04:29 2003 for GLText by doxygen1.3-rc1