AppSrc/glfont2.cpp
changeset 3 93fff7023be8
equal deleted inserted replaced
2:e1e28b0273b0 3:93fff7023be8
       
     1 //*******************************************************************
       
     2 // glfont2.cpp -- glFont Version 2.0 implementation
       
     3 // Copyright (c) 1998-2002 Brad Fish
       
     4 // See glfont.html for terms of use
       
     5 // May 14, 2002
       
     6 //
       
     7 // Symbian OS port - June 2007
       
     8 // Luis Valente - lpvalente@gmail.com
       
     9 //
       
    10 //*******************************************************************
       
    11  
       
    12 /*
       
    13 This font class is intended to render 2D text. So, it is important to set up the 
       
    14 required orthographic projection before rendering. The following code is an 
       
    15 example of how to do this: 
       
    16 
       
    17 // Rect() is a method that returns the current drawing rectangle.
       
    18 // The (0,0) point will be the on bottom-left corner.
       
    19  
       
    20 glViewport (0, 0, Rect().Width(), Rect().Height());
       
    21     
       
    22 glMatrixMode (GL_PROJECTION);
       
    23   glLoadIdentity ();
       
    24   glOrthox (0, IntToFixed (Rect().Width()), 0, IntToFixed (Rect().Height()), -1, 1);
       
    25     
       
    26  glMatrixMode (GL_MODELVIEW);
       
    27    glLoadIdentity ();Also, the BeginDraw() and EndDraw() methods (or equivalent code) should be called 
       
    28    to set up required states for rendering. For example, if alpha blending is not enabled, the quad 
       
    29    corresponding to the character becomes noticeable. 
       
    30 
       
    31 Currently, this class supports 8 bit descriptors only. The class should be extended to support 16 bits 
       
    32 descriptors and resource strings. 
       
    33 
       
    34 */
       
    35 
       
    36 // Symbian OS headers
       
    37 #include <s32file.h>
       
    38 #include <eikenv.h>
       
    39 #include <eikappui.h>
       
    40 #include <eikapp.h>
       
    41 #include "glfont2.h"
       
    42 #include "FixedMath.h"
       
    43  
       
    44  
       
    45 // GLFontChar structure as stored in file
       
    46 struct GLFontCharFile
       
    47 {
       
    48    TReal32 dx, dy;
       
    49    TReal32 tx1, ty1;
       
    50    TReal32 tx2, ty2;
       
    51 };
       
    52  
       
    53 // GLFontHeaderFile structure as stored in file
       
    54 struct GLFontHeaderFile
       
    55 {
       
    56    TInt32  tex;
       
    57    TInt32  texWidth, texHeight;
       
    58    TInt32  startChar, endChar;
       
    59    TUint32 chars;
       
    60 };
       
    61  
       
    62  
       
    63  
       
    64 //_____________________________________________________________________________
       
    65 //
       
    66 // Default constructor.
       
    67 //
       
    68  
       
    69 GLFont::GLFont ()
       
    70 {
       
    71    // Initialize iHeader to safe state
       
    72    iHeader.tex = 0;
       
    73    iHeader.texWidth = 0;
       
    74    iHeader.texHeight = 0;
       
    75    iHeader.startChar = 0;
       
    76    iHeader.endChar = 0;
       
    77    iHeader.chars = NULL;
       
    78  
       
    79    // OpenGL texture
       
    80    glGenTextures (1, &iHeader.tex);
       
    81 }
       
    82  
       
    83 //_____________________________________________________________________________
       
    84 //
       
    85 // Destructor.
       
    86 //
       
    87  
       
    88 GLFont::~GLFont ()
       
    89 {
       
    90    // Destroy the font
       
    91    Destroy();
       
    92  
       
    93    // delete texture
       
    94    glDeleteTextures (1, &iHeader.tex);
       
    95 }
       
    96  
       
    97 //_____________________________________________________________________________
       
    98 //
       
    99 // Factory-method.
       
   100 //
       
   101  
       
   102 GLFont * GLFont::NewL (const TDesC & aFilename)
       
   103 {
       
   104    GLFont* f = new (ELeave) GLFont();
       
   105    CleanupStack::PushL (f);
       
   106  
       
   107    f->ConstructL (aFilename);
       
   108  
       
   109    CleanupStack::Pop ();
       
   110    return f;
       
   111 }
       
   112  
       
   113 //_____________________________________________________________________________
       
   114 //
       
   115 // Second part of the two-phase construction.
       
   116 //
       
   117  
       
   118 void GLFont::ConstructL (const TDesC & aFilename)
       
   119 {
       
   120    // Destroy the old font if there was one, just to be safe
       
   121    Destroy();
       
   122  
       
   123    // Open file session with server	
       
   124    RFs session;
       
   125    User::LeaveIfError (session.Connect());
       
   126    CleanupClosePushL (session);	
       
   127  
       
   128    // retrieve private application folder
       
   129    TFileName path;
       
   130    session.PrivatePath (path);
       
   131  
       
   132    // retrieve full application path on device
       
   133    #ifndef __WINS__
       
   134       TFileName appFullName =          
       
   135       CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
       
   136  
       
   137       TParse parse;
       
   138       parse.Set (appFullName, NULL, NULL);
       
   139       path.Insert (0, parse.Drive());
       
   140    #endif
       
   141  
       
   142    // update filename with full path
       
   143    TFileName fullFilename (path);
       
   144    fullFilename.Append (aFilename);
       
   145  
       
   146    // load file
       
   147    LoadFileL (session, fullFilename);
       
   148  
       
   149    // close server session
       
   150    CleanupStack::PopAndDestroy();
       
   151  
       
   152 }
       
   153  
       
   154 //_____________________________________________________________________________
       
   155 //
       
   156 // Loads the font file.
       
   157 //
       
   158  
       
   159 void GLFont::LoadFileL (RFs & aFs, const TDesC & aFilename)
       
   160 {
       
   161    // Open input file
       
   162    RFileReadStream readStream;
       
   163  
       
   164    User::LeaveIfError (readStream.Open (aFs, aFilename, EFileRead));	
       
   165    readStream.PushL();
       
   166  
       
   167    // Read the iHeader from file
       
   168    GLFontHeaderFile headerFile;
       
   169  
       
   170    headerFile.tex       = readStream.ReadInt32L ();
       
   171    headerFile.texWidth  = readStream.ReadInt32L();
       
   172    headerFile.texHeight = readStream.ReadInt32L();
       
   173    headerFile.startChar = readStream.ReadInt32L();
       
   174    headerFile.endChar   = readStream.ReadInt32L();
       
   175    headerFile.chars     = readStream.ReadUint32L();
       
   176  
       
   177    // copy iHeader file to actual iHeader		
       
   178    iHeader.texWidth  = headerFile.texWidth;
       
   179    iHeader.texHeight = headerFile.texHeight;
       
   180    iHeader.startChar = headerFile.startChar;
       
   181    iHeader.endChar   = headerFile.endChar;
       
   182  
       
   183    // Allocate space for character array
       
   184    TInt numChars = iHeader.endChar - iHeader.startChar + 1;	
       
   185    iHeader.chars = new (ELeave) GLFontChar [numChars];
       
   186  
       
   187    // Read character array
       
   188    for (TInt i = 0; i < numChars; ++i)
       
   189    {
       
   190       iHeader.chars [i].dx  =  FloatToFixed (readStream.ReadReal32L () );		
       
   191       iHeader.chars [i].dy  =  FloatToFixed (readStream.ReadReal32L () );		
       
   192       iHeader.chars [i].tx1 =  FloatToFixed (readStream.ReadReal32L () );		
       
   193       iHeader.chars [i].ty1 =  FloatToFixed (readStream.ReadReal32L () );		
       
   194       iHeader.chars [i].tx2 =  FloatToFixed (readStream.ReadReal32L () );		
       
   195       iHeader.chars [i].ty2 =  FloatToFixed (readStream.ReadReal32L () );
       
   196    }
       
   197  
       
   198  
       
   199    // Read texture pixel data
       
   200    TInt numTexBytes = iHeader.texWidth * iHeader.texHeight * 2;	
       
   201    TUint8 * texBytes = new (ELeave) TUint8 [numTexBytes]; CleanupStack::PushL (texBytes);
       
   202  
       
   203    readStream.ReadL (texBytes, numTexBytes);	
       
   204  
       
   205    // Create OpenGL texture
       
   206    glBindTexture   (GL_TEXTURE_2D, iHeader.tex);  
       
   207    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
       
   208    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
       
   209    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
   210    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
   211    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
       
   212  
       
   213    glTexImage2D (GL_TEXTURE_2D,
       
   214                  0,
       
   215                  GL_LUMINANCE_ALPHA,
       
   216                  iHeader.texWidth,
       
   217                  iHeader.texHeight,
       
   218                  0,
       
   219                  GL_LUMINANCE_ALPHA,
       
   220                  GL_UNSIGNED_BYTE,
       
   221                  (GLvoid *)texBytes);
       
   222  
       
   223    // Free texture pixels memory
       
   224    CleanupStack::Pop ();
       
   225    delete [] texBytes;	
       
   226  
       
   227    // Close input file
       
   228    readStream.Close();
       
   229    readStream.Pop();
       
   230 }
       
   231  
       
   232 //_____________________________________________________________________________
       
   233 //
       
   234 // Font destruction.
       
   235 //
       
   236  
       
   237 void GLFont::Destroy ()
       
   238 {
       
   239    //Delete the character array if necessary
       
   240    if (iHeader.chars)
       
   241    {
       
   242       delete [] iHeader.chars;
       
   243       iHeader.chars = 0;
       
   244    }
       
   245 }
       
   246  
       
   247 //_____________________________________________________________________________
       
   248 //
       
   249 // Retrieves the texture dimensions.
       
   250 //
       
   251  
       
   252 void GLFont::GetTexSize (TInt & aWidth, TInt & aHeight)
       
   253 {	
       
   254    aWidth  = iHeader.texWidth;
       
   255    aHeight = iHeader.texHeight;
       
   256 }
       
   257  
       
   258 //_____________________________________________________________________________
       
   259 //
       
   260 // Retrieves the character interval.
       
   261 //
       
   262  
       
   263 void GLFont::GetCharInterval (TInt & aStart, TInt & aEnd)
       
   264 {	
       
   265    aStart = iHeader.startChar;
       
   266    aEnd   = iHeader.endChar;
       
   267 }
       
   268  
       
   269 //_____________________________________________________________________________
       
   270 //
       
   271 // Retrieves the dimensions of a character.
       
   272 //
       
   273  
       
   274 void GLFont::GetCharSize (TText8 aChar, TInt & aWidth, TInt aHeight)
       
   275 {
       
   276    // Make sure character is in range
       
   277    if (aChar < iHeader.startChar || aChar > iHeader.endChar)
       
   278    {
       
   279       // Not a valid character, so it obviously has no size
       
   280       aWidth  = 0;
       
   281       aHeight = 0;
       
   282    }
       
   283    else
       
   284    {
       
   285       GLFontChar* fontChar;
       
   286  
       
   287       // Retrieve character size
       
   288       fontChar = & iHeader.chars [aChar - iHeader.startChar];		
       
   289       aWidth  = FixedToInt (MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) ) );
       
   290       aHeight = FixedToInt (MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) ) );		
       
   291    }
       
   292 }
       
   293  
       
   294 //_____________________________________________________________________________
       
   295 //
       
   296 // Retrieves the dimensions of a string.
       
   297 //
       
   298  
       
   299 void GLFont::GetStringSize (const TDesC8 & aText, TInt & aWidth, TInt & aHeight)
       
   300 {	
       
   301    // Height is the same for now...might change in future
       
   302    aHeight = FixedToInt (MultiplyFixed (iHeader.chars [iHeader.startChar].dy, IntToFixed (iHeader.texHeight) ) ); 
       
   303  
       
   304    // texWidth as fixed
       
   305    const GLfixed texWidthx = IntToFixed (iHeader.texWidth);
       
   306  
       
   307    // Calculate width of string	
       
   308    GLfixed widthx = 0;
       
   309    for (TInt i = 0; i < aText.Length(); i++)
       
   310    {
       
   311       // Make sure character is in range
       
   312       const TText8 c = aText [i];
       
   313       if (c < iHeader.startChar || c > iHeader.endChar)
       
   314          continue;
       
   315  
       
   316       // Get pointer to glFont character
       
   317       const GLFontChar* fontChar = & iHeader.chars [c - iHeader.startChar];
       
   318  
       
   319       // Get width and height
       
   320       widthx += MultiplyFixed (fontChar->dx, texWidthx);		
       
   321    }
       
   322  
       
   323    // Save width
       
   324    aWidth = FixedToInt (widthx);
       
   325 }
       
   326  
       
   327 //_____________________________________________________________________________
       
   328 //
       
   329 // Renders a string. Reference point is top-left.
       
   330 //
       
   331  
       
   332 void GLFont::DrawString (const TDesC8 & aText, GLfixed aX, GLfixed aY)
       
   333 {
       
   334    // vertex arrays to render the string
       
   335    GLfixed  vertices [4*2];
       
   336    GLfixed texCoords [4*2];	
       
   337    const GLubyte indices [] = {1, 2, 0, 3};
       
   338  
       
   339    glVertexPointer  (2, GL_FIXED, 0, vertices);
       
   340    glTexCoordPointer (2, GL_FIXED, 0, texCoords); 	
       
   341  
       
   342    // Bind texture
       
   343    glBindTexture (GL_TEXTURE_2D, iHeader.tex);
       
   344  
       
   345    // Loop through characters
       
   346    for (TInt i = 0; i < aText.Length(); i++)
       
   347    {
       
   348       // Make sure character is in range
       
   349       TText8 c = aText [i];
       
   350       if (c < iHeader.startChar || c > iHeader.endChar)
       
   351          continue;
       
   352  
       
   353       // Get pointer to glFont character
       
   354       GLFontChar* fontChar = &iHeader.chars [c - iHeader.startChar];
       
   355  
       
   356       // Get width and height
       
   357       GLfixed width =  MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) );
       
   358       GLfixed height = MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) );
       
   359  
       
   360       // Specify texture coordinates
       
   361       texCoords [0] = fontChar->tx1; texCoords [1] = fontChar->ty1;
       
   362       texCoords [2] = fontChar->tx1; texCoords [3] = fontChar->ty2;
       
   363  
       
   364       texCoords [4] = fontChar->tx2; texCoords [5] = fontChar->ty2;
       
   365       texCoords [6] = fontChar->tx2; texCoords [7] = fontChar->ty1;
       
   366  
       
   367       // and vertices
       
   368       vertices [0] = aX;         vertices [1] = aY;
       
   369       vertices [2] = aX;         vertices [3] = aY - height;
       
   370    
       
   371       vertices [4] = aX + width; vertices [5] = aY - height;
       
   372       vertices [6] = aX + width; vertices [7] = aY;
       
   373  
       
   374       // draw
       
   375       glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
       
   376  
       
   377       // Move to next character
       
   378       aX += width;
       
   379    }
       
   380  
       
   381 }