AppSrc/glfont2.cpp
changeset 3 93fff7023be8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppSrc/glfont2.cpp	Fri Oct 15 10:18:29 2010 +0900
@@ -0,0 +1,381 @@
+//*******************************************************************
+// glfont2.cpp -- glFont Version 2.0 implementation
+// Copyright (c) 1998-2002 Brad Fish
+// See glfont.html for terms of use
+// May 14, 2002
+//
+// Symbian OS port - June 2007
+// Luis Valente - lpvalente@gmail.com
+//
+//*******************************************************************
+ 
+/*
+This font class is intended to render 2D text. So, it is important to set up the 
+required orthographic projection before rendering. The following code is an 
+example of how to do this: 
+
+// Rect() is a method that returns the current drawing rectangle.
+// The (0,0) point will be the on bottom-left corner.
+ 
+glViewport (0, 0, Rect().Width(), Rect().Height());
+    
+glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrthox (0, IntToFixed (Rect().Width()), 0, IntToFixed (Rect().Height()), -1, 1);
+    
+ glMatrixMode (GL_MODELVIEW);
+   glLoadIdentity ();Also, the BeginDraw() and EndDraw() methods (or equivalent code) should be called 
+   to set up required states for rendering. For example, if alpha blending is not enabled, the quad 
+   corresponding to the character becomes noticeable. 
+
+Currently, this class supports 8 bit descriptors only. The class should be extended to support 16 bits 
+descriptors and resource strings. 
+
+*/
+
+// Symbian OS headers
+#include <s32file.h>
+#include <eikenv.h>
+#include <eikappui.h>
+#include <eikapp.h>
+#include "glfont2.h"
+#include "FixedMath.h"
+ 
+ 
+// GLFontChar structure as stored in file
+struct GLFontCharFile
+{
+   TReal32 dx, dy;
+   TReal32 tx1, ty1;
+   TReal32 tx2, ty2;
+};
+ 
+// GLFontHeaderFile structure as stored in file
+struct GLFontHeaderFile
+{
+   TInt32  tex;
+   TInt32  texWidth, texHeight;
+   TInt32  startChar, endChar;
+   TUint32 chars;
+};
+ 
+ 
+ 
+//_____________________________________________________________________________
+//
+// Default constructor.
+//
+ 
+GLFont::GLFont ()
+{
+   // Initialize iHeader to safe state
+   iHeader.tex = 0;
+   iHeader.texWidth = 0;
+   iHeader.texHeight = 0;
+   iHeader.startChar = 0;
+   iHeader.endChar = 0;
+   iHeader.chars = NULL;
+ 
+   // OpenGL texture
+   glGenTextures (1, &iHeader.tex);
+}
+ 
+//_____________________________________________________________________________
+//
+// Destructor.
+//
+ 
+GLFont::~GLFont ()
+{
+   // Destroy the font
+   Destroy();
+ 
+   // delete texture
+   glDeleteTextures (1, &iHeader.tex);
+}
+ 
+//_____________________________________________________________________________
+//
+// Factory-method.
+//
+ 
+GLFont * GLFont::NewL (const TDesC & aFilename)
+{
+   GLFont* f = new (ELeave) GLFont();
+   CleanupStack::PushL (f);
+ 
+   f->ConstructL (aFilename);
+ 
+   CleanupStack::Pop ();
+   return f;
+}
+ 
+//_____________________________________________________________________________
+//
+// Second part of the two-phase construction.
+//
+ 
+void GLFont::ConstructL (const TDesC & aFilename)
+{
+   // Destroy the old font if there was one, just to be safe
+   Destroy();
+ 
+   // Open file session with server	
+   RFs session;
+   User::LeaveIfError (session.Connect());
+   CleanupClosePushL (session);	
+ 
+   // retrieve private application folder
+   TFileName path;
+   session.PrivatePath (path);
+ 
+   // retrieve full application path on device
+   #ifndef __WINS__
+      TFileName appFullName =          
+      CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
+ 
+      TParse parse;
+      parse.Set (appFullName, NULL, NULL);
+      path.Insert (0, parse.Drive());
+   #endif
+ 
+   // update filename with full path
+   TFileName fullFilename (path);
+   fullFilename.Append (aFilename);
+ 
+   // load file
+   LoadFileL (session, fullFilename);
+ 
+   // close server session
+   CleanupStack::PopAndDestroy();
+ 
+}
+ 
+//_____________________________________________________________________________
+//
+// Loads the font file.
+//
+ 
+void GLFont::LoadFileL (RFs & aFs, const TDesC & aFilename)
+{
+   // Open input file
+   RFileReadStream readStream;
+ 
+   User::LeaveIfError (readStream.Open (aFs, aFilename, EFileRead));	
+   readStream.PushL();
+ 
+   // Read the iHeader from file
+   GLFontHeaderFile headerFile;
+ 
+   headerFile.tex       = readStream.ReadInt32L ();
+   headerFile.texWidth  = readStream.ReadInt32L();
+   headerFile.texHeight = readStream.ReadInt32L();
+   headerFile.startChar = readStream.ReadInt32L();
+   headerFile.endChar   = readStream.ReadInt32L();
+   headerFile.chars     = readStream.ReadUint32L();
+ 
+   // copy iHeader file to actual iHeader		
+   iHeader.texWidth  = headerFile.texWidth;
+   iHeader.texHeight = headerFile.texHeight;
+   iHeader.startChar = headerFile.startChar;
+   iHeader.endChar   = headerFile.endChar;
+ 
+   // Allocate space for character array
+   TInt numChars = iHeader.endChar - iHeader.startChar + 1;	
+   iHeader.chars = new (ELeave) GLFontChar [numChars];
+ 
+   // Read character array
+   for (TInt i = 0; i < numChars; ++i)
+   {
+      iHeader.chars [i].dx  =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].dy  =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].tx1 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].ty1 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].tx2 =  FloatToFixed (readStream.ReadReal32L () );		
+      iHeader.chars [i].ty2 =  FloatToFixed (readStream.ReadReal32L () );
+   }
+ 
+ 
+   // Read texture pixel data
+   TInt numTexBytes = iHeader.texWidth * iHeader.texHeight * 2;	
+   TUint8 * texBytes = new (ELeave) TUint8 [numTexBytes]; CleanupStack::PushL (texBytes);
+ 
+   readStream.ReadL (texBytes, numTexBytes);	
+ 
+   // Create OpenGL texture
+   glBindTexture   (GL_TEXTURE_2D, iHeader.tex);  
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ 
+   glTexImage2D (GL_TEXTURE_2D,
+                 0,
+                 GL_LUMINANCE_ALPHA,
+                 iHeader.texWidth,
+                 iHeader.texHeight,
+                 0,
+                 GL_LUMINANCE_ALPHA,
+                 GL_UNSIGNED_BYTE,
+                 (GLvoid *)texBytes);
+ 
+   // Free texture pixels memory
+   CleanupStack::Pop ();
+   delete [] texBytes;	
+ 
+   // Close input file
+   readStream.Close();
+   readStream.Pop();
+}
+ 
+//_____________________________________________________________________________
+//
+// Font destruction.
+//
+ 
+void GLFont::Destroy ()
+{
+   //Delete the character array if necessary
+   if (iHeader.chars)
+   {
+      delete [] iHeader.chars;
+      iHeader.chars = 0;
+   }
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the texture dimensions.
+//
+ 
+void GLFont::GetTexSize (TInt & aWidth, TInt & aHeight)
+{	
+   aWidth  = iHeader.texWidth;
+   aHeight = iHeader.texHeight;
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the character interval.
+//
+ 
+void GLFont::GetCharInterval (TInt & aStart, TInt & aEnd)
+{	
+   aStart = iHeader.startChar;
+   aEnd   = iHeader.endChar;
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the dimensions of a character.
+//
+ 
+void GLFont::GetCharSize (TText8 aChar, TInt & aWidth, TInt aHeight)
+{
+   // Make sure character is in range
+   if (aChar < iHeader.startChar || aChar > iHeader.endChar)
+   {
+      // Not a valid character, so it obviously has no size
+      aWidth  = 0;
+      aHeight = 0;
+   }
+   else
+   {
+      GLFontChar* fontChar;
+ 
+      // Retrieve character size
+      fontChar = & iHeader.chars [aChar - iHeader.startChar];		
+      aWidth  = FixedToInt (MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) ) );
+      aHeight = FixedToInt (MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) ) );		
+   }
+}
+ 
+//_____________________________________________________________________________
+//
+// Retrieves the dimensions of a string.
+//
+ 
+void GLFont::GetStringSize (const TDesC8 & aText, TInt & aWidth, TInt & aHeight)
+{	
+   // Height is the same for now...might change in future
+   aHeight = FixedToInt (MultiplyFixed (iHeader.chars [iHeader.startChar].dy, IntToFixed (iHeader.texHeight) ) ); 
+ 
+   // texWidth as fixed
+   const GLfixed texWidthx = IntToFixed (iHeader.texWidth);
+ 
+   // Calculate width of string	
+   GLfixed widthx = 0;
+   for (TInt i = 0; i < aText.Length(); i++)
+   {
+      // Make sure character is in range
+      const TText8 c = aText [i];
+      if (c < iHeader.startChar || c > iHeader.endChar)
+         continue;
+ 
+      // Get pointer to glFont character
+      const GLFontChar* fontChar = & iHeader.chars [c - iHeader.startChar];
+ 
+      // Get width and height
+      widthx += MultiplyFixed (fontChar->dx, texWidthx);		
+   }
+ 
+   // Save width
+   aWidth = FixedToInt (widthx);
+}
+ 
+//_____________________________________________________________________________
+//
+// Renders a string. Reference point is top-left.
+//
+ 
+void GLFont::DrawString (const TDesC8 & aText, GLfixed aX, GLfixed aY)
+{
+   // vertex arrays to render the string
+   GLfixed  vertices [4*2];
+   GLfixed texCoords [4*2];	
+   const GLubyte indices [] = {1, 2, 0, 3};
+ 
+   glVertexPointer  (2, GL_FIXED, 0, vertices);
+   glTexCoordPointer (2, GL_FIXED, 0, texCoords); 	
+ 
+   // Bind texture
+   glBindTexture (GL_TEXTURE_2D, iHeader.tex);
+ 
+   // Loop through characters
+   for (TInt i = 0; i < aText.Length(); i++)
+   {
+      // Make sure character is in range
+      TText8 c = aText [i];
+      if (c < iHeader.startChar || c > iHeader.endChar)
+         continue;
+ 
+      // Get pointer to glFont character
+      GLFontChar* fontChar = &iHeader.chars [c - iHeader.startChar];
+ 
+      // Get width and height
+      GLfixed width =  MultiplyFixed (fontChar->dx, IntToFixed (iHeader.texWidth) );
+      GLfixed height = MultiplyFixed (fontChar->dy, IntToFixed (iHeader.texHeight) );
+ 
+      // Specify texture coordinates
+      texCoords [0] = fontChar->tx1; texCoords [1] = fontChar->ty1;
+      texCoords [2] = fontChar->tx1; texCoords [3] = fontChar->ty2;
+ 
+      texCoords [4] = fontChar->tx2; texCoords [5] = fontChar->ty2;
+      texCoords [6] = fontChar->tx2; texCoords [7] = fontChar->ty1;
+ 
+      // and vertices
+      vertices [0] = aX;         vertices [1] = aY;
+      vertices [2] = aX;         vertices [3] = aY - height;
+   
+      vertices [4] = aX + width; vertices [5] = aY - height;
+      vertices [6] = aX + width; vertices [7] = aY;
+ 
+      // draw
+      glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
+ 
+      // Move to next character
+      aX += width;
+   }
+ 
+}
\ No newline at end of file