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 }