winfont.cpp

00001 // NOT A PART OF GLICT.
00002 // This code is not licensed under GNU GPL.
00003 
00004 #include <windows.h>
00005 #include <GL/gl.h>
00006 #include <stdio.h>
00007 #include "winfont.h"
00008 WinFontStruct *WinFontCreate(char* fontname, char style, char size) {
00009         HFONT   font;                                           // Windows Font ID
00010         GLuint  base;
00011         GLYPHMETRICSFLOAT gmf[256];
00012         base = glGenLists(256);                                 // Storage For 256 Characters
00013 
00014 
00015         // Height
00016         //By putting a minus, we're telling windows to find us a font based on the CHARACTER height.
00017         //If we use a positive number we match the font based on the CELL height.
00018 
00019         // Width
00020         //Then we specify the cell width. You'll notice I have it set to 0.
00021         //By setting values to 0, windows will use the default value.
00022         //You can play around with this value if you want. Make the font wide, etc.
00023 
00024         // Angle
00025         //Angle of Escapement will rotate the font. Orientation Angle quoted from MSDN help
00026         //Specifies the angle, in tenths of degrees, between each character's base line and
00027         //the x-axis of the device.
00028         //Unfortunately I have no idea what that means :(
00029 
00030         // Weight
00031         //Font weight is a great parameter. You can put a number from 0 - 1000 or you can use
00032         //one of the predefined values. FW_DONTCARE is 0, FW_NORMAL is 400, FW_BOLD is 700
00033         //and FW_BLACK is 900. There are alot more predefined values, but those 4 give some
00034         //good variety. The higher the value, the thicker the font (more bold).
00035 
00036         // Style
00037         //Italic, Underline and Strikeout can be either TRUE or FALSE. Basically if underline
00038         //is TRUE, the font will be underlined. If it's FALSE it wont be. Pretty simple :)
00039 
00040         // Charset
00041         //Character set Identifier describes the type of Character set you wish to use.
00042         //There are too many types to explain. CHINESEBIG5_CHARSET, GREEK_CHARSET, RUSSIAN_CHARSET,
00043         //DEFAULT_CHARSET, etc. ANSI is the one I use, although DEFAULT would probably work
00044         //just as well.
00045         //If you're interested in using a font such as Webdings or Wingdings, you need to use
00046         //SYMBOL_CHARSET instead of ANSI_CHARSET.
00047 
00048         // Precision
00049         //Output Precision is very important. It tells Windows what type of character set
00050         //to use if there is more than one type available. OUT_TT_PRECIS tells Windows that
00051         //if there is more than one type of font to choose from with the same name, select
00052         //the TRUETYPE version of the font. Truetype fonts always look better, especially
00053         //when you make them large. You can also use OUT_TT_ONLY_PRECIS, which ALWAYS trys
00054         //to use a TRUETYPE Font.
00055 
00056         // Clipping Precision
00057         //is the type of clipping to do on the font if it goes outside the clipping region.
00058         //Not much to say about this, just leave it set to default.
00059 
00060         // Output Quality
00061         //is very important.you can have PROOF, DRAFT, NONANTIALIASED, DEFAULT or ANTIALIASED.
00062         //We all know that ANTIALIASED fonts look good :) Antialiasing a font is the same effect
00063         //you get when you turn on font smoothing in Windows. It makes everything look less jagged.
00064 
00065         // Family and Pitch
00066         //Next we have the Family and Pitch settings. For pitch you can have DEFAULT_PITCH,
00067         //FIXED_PITCH and VARIABLE_PITCH, and for family you can have FF_DECORATIVE, FF_MODERN,
00068         //FF_ROMAN, FF_SCRIPT, FF_SWISS, FF_DONTCARE. Play around with them to find out what
00069         //they do. I just set them both to default.
00070 
00071         // Font name
00072         //Finally... We have the actual name of the font. Boot up Microsoft Word or some other
00073         //text editor. Click on the font drop down menu, and find a font you like. To use the
00074         //font, replace 'Comic Sans MS' with the name of the font you'd rather use.
00075 
00076         font = CreateFont(      -12,                                                                                            // Height Of Font
00077                                                 0,                                                                                                      // Width Of Font
00078                                                 0,                                                                                                      // Angle Of Escapement
00079                                                 0,                                                                                                      // Orientation Angle
00080                                                 (style & WINFONT_BOLD) ? FW_BOLD : FW_DONTCARE,         // Font Weight
00081                                                 style & WINFONT_ITALIC,                                                         // Italic
00082                                                 style & WINFONT_UNDERLINE,                                                      // Underline
00083                                                 style & WINFONT_STRIKEOUT,                                                      // Strikeout
00084                                                 ANSI_CHARSET,                                                                           // Character Set Identifier
00085                                                 OUT_TT_PRECIS,                                                                          // Output Precision
00086                                                 CLIP_DEFAULT_PRECIS,                                                            // Clipping Precision
00087                                                 ANTIALIASED_QUALITY,                                                            // Output Quality
00088                                                 FF_DONTCARE|DEFAULT_PITCH,                                                      // Family And Pitch
00089                                                 fontname);                                                                                      // Font Name
00090 
00091         if (!font) {
00092                 MessageBox(HWND_DESKTOP, "Failed to create font.", 0,0);
00093                 return NULL;
00094         }
00095 
00096         HDC hDC = CreateCompatibleDC(GetDC(HWND_DESKTOP)); //"DISPLAY", NULL, NULL, NULL);
00097         if (!hDC) {
00098                 MessageBox(HWND_DESKTOP, "Failed to create font.", 0,0);
00099                 return NULL;
00100         }
00101         SelectObject(hDC, font);                                // Selects The Font We Created
00102 
00103         //Now for the new code. We build our Outline font using a new command wglUseFontOutlines.
00104         //We select our DC, the starting character, the number of characters to create and the
00105         //'base' display list value. All very similar to the way we built our Bitmap font.
00106 
00107 
00108         //That's not all however. We then set the deviation level. The closer to 0.0f, the
00109         //smooth the font will look. After we set the deviation, we get to set the font
00110         //thickness. This describes how thick the font is on the Z axis. 0.0f will produce
00111         //a flat 2D looking font and 1.0f will produce a font with some depth.
00112 
00113         //The parameter WGL_FONT_POLYGONS tells OpenGL to create a solid font using polygons.
00114         //If we use WGL_FONT_LINES instead, the font will be wireframe (made of lines).
00115         //It's also important to note that if you use GL_FONT_LINES, normals will not be
00116         //generated so lighting will not work properly.
00117 
00118         //The last parameter gmf points to the address buffer for the display list data.
00119 
00120 
00121         wglUseFontOutlines(     hDC,                            // Select The Current DC
00122                                                 0,                                      // Starting Character
00123                                                 255,                            // Number Of Display Lists To Build
00124                                                 base,                           // Starting Display Lists
00125                                                 1.0f,                           // Deviation From The True Outlines
00126                                                 0.0f,                           // Font Thickness In The Z Direction
00127                                                 WGL_FONT_POLYGONS,      // Use Polygons, Not Lines
00128                                                 gmf);                           // Address Of Buffer To Recieve Data
00129 
00130         //wglUseFontBitmaps (hDC, 0, 255, base);
00131         DeleteObject(font);
00132         DeleteDC(hDC);
00133 
00134         WinFontStruct *font_struct;
00135         font_struct = (WinFontStruct*)malloc(sizeof(WinFontStruct));
00136         font_struct->base = base;
00137         memcpy(font_struct->gmf, gmf, sizeof(gmf[0])*256);
00138         return font_struct;
00139 }
00140 
00141 void WinFontDelete(void* fontvoid) {
00142         if (fontvoid) {
00143                 WinFontStruct *font = (WinFontStruct*)fontvoid;
00144                 glDeleteLists(font->base, 256);
00145                 free(font);
00146         }
00147 }
00148 
00149 void WinFontDraw(const char* txt, const void* fontvoid, float x, float y) {
00150         WinFontStruct *font = ((WinFontStruct*)fontvoid);
00151 
00152         glPushAttrib(GL_LIST_BIT|GL_POLYGON_BIT);                               // Pushes The Display List Bits
00153         glListBase(font->base);                                 // Sets The Base Character to 0
00154 
00155         glCullFace(GL_BACK);
00156         glEnable (GL_CULL_FACE);
00157 
00158         glPushMatrix();
00159 
00160         glTranslatef(x,y,0);
00161         glScalef(1.5,1.5,1.);
00162         //glCallLists(strlen(txt), GL_UNSIGNED_BYTE, txt);      // Draws The Display List Text
00163         unsigned int sizesofar = 0.;
00164         for (unsigned char *t = (unsigned char*)txt; *t; ++t) {
00165                 switch (*t) {
00166                         default:
00167                                 glCallLists(1, GL_UNSIGNED_BYTE, t);
00168                                 sizesofar += (font->gmf[*t].gmfCellIncX * (1 << 16));
00169                                 break;
00170                         case '\n':
00171                         case '\r':
00172                                 glTranslatef(-(sizesofar / (float)(1 << 16)), -(float)(font->gmf['a'].gmfBlackBoxY) * 1.6 ,0);
00173                                 sizesofar = 0;
00174                                 if (*t == '\n' && *(t+1)=='\r' || *t == '\r' && *(t+1)=='\n' ) t++;
00175                 break;
00176 
00177 
00178                 }
00179         }
00180         glPopMatrix();
00181 
00182         glPopAttrib();
00183 }
00184 
00185 // possibly it might be a good idea to rewrite this?
00186 float WinFontSize(const char* text, const void* fontvoid) {
00187         WinFontStruct* font = (WinFontStruct*)fontvoid;
00188 
00189         float length=0.;
00190         for (char *t=(char*)text;*t;++t)        // Loop To Find Text Length
00191         {
00192                 length+=font->gmf[*t].gmfCellIncX;              // Increase Length By Each Characters Width
00193         }
00194         return length*1.5;
00195 }

SourceForge.net Logo
generated with doxygen 1.5.3 on Mon Oct 29 18:09:26 2007