Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
font.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2003 Mike Byron
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include "vegastrike.h"
23 
24 #include "font.h"
25 
26 #include "guidefs.h"
27 #include "vs_globals.h"
28 #include "config_xml.h"
29 //For some reason, the cumulative width of GLUT strings is smaller than the
30 //actual width when they are painted. If we add this factor to the reference
31 //length of every GLUT character, things work a lot better.
32 //It looks like the reason is that the return type for getting GLUT reference lengths
33 //is int, and the lengths are not int. The character drawing code lets GLUT move the
34 //origin for each character, and it looks like that movement is not integer in the
35 //reference char space (it's clearly not going to be integer in the scaled space).
36 static const double GLUT_WIDTH_HACK = 0.6;
37 
38 //The width of the space character in the outline font is too big, so we make it a special case.
39 static const char SPACE_CHAR = ' ';
40 
41 bool useStroke()
42 {
43  static bool tmp =
44  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "high_quality_font_computer",
45  vs_config->getVariable( "graphics", "high_quality_font", "false" ) ) );
46  return !tmp;
47 }
48 //Calculate the metrics for this font.
49 //This does the real work, and doesn't check whether it needs to be done.
50 void Font::calcMetrics( void )
51 {
52  //This is a hack to adjust the font stroke width as the font size goes up.
53  //Since the stroke width is in pixels, we scale the width up as the screen resolution gets
54  //higher. (Currently, this is linear, which doesn't work well at small sizes.)
55  //We also make sure the stroke width is at least 1.0. Otherwise antialiasing causes
56  //some font features to fade out.
57  //My OpenGL (Windows XP) has a max line width of 10. So we get stroke width truncation for font
58  //size over 0.5. This is OK because the curves look really ugly that big anyway.
59  const double referenceStrokeWidth = 20.0; //Best width for a font size of 1.0 (big).
60  const double referenceStrokeWidthResolution = 800; //X-resolution stroke width measured in.
61  const double minimumStrokeWidth = 1.0;
62 
63  const double nonClippedStrokeWidth = size()*referenceStrokeWidth*strokeWeight()
64  *(g_game.x_resolution/referenceStrokeWidthResolution);
65 
66  m_strokeWidth = guiMax( minimumStrokeWidth, nonClippedStrokeWidth );
67  m_needMetrics = false;
68 
69  //Vertical scaling factor:
71  //Horizontal scaling factor. Same as vertical, except we need to make the coord system
72  //the same distance in all directions, so we need to apply the ratio of vert / horiz
73  //resolution. Otherwise the fonts are slightly stretched horizontally -- there
74  //are more pixels horizontally than vertically per unit in the identity coord space.
75  if ( useStroke() )
77  else
78  //Calculation above seems broken... this seems to work for most sizes with bitmap.
80  //The size of a horizontal pixel in reference space.
81  const double horizPixelInRefSpace = REFERENCE_LINE_SPACING/(g_game.x_resolution/2)/size();
82 
83  //Recalculate the extra char width.
84  m_extraCharWidth = horizPixelInRefSpace*m_strokeWidth;
85 
86  //Space character width should be the same as a number.
87  //Numbers are generally all the same width so you can assume they will go into columns.
88  //We use '8' because if the numbers aren't all the same width, '8' is a good, wide number.
89  //What we calculate here is the horizontal translation to get from the actual outline font
90  //space char width to the space char width we want.
91  const double eightWidth = glutStrokeWidth( GLUT_STROKE_ROMAN, '8' )+m_extraCharWidth;
92  m_spaceCharFixup = eightWidth-glutStrokeWidth( GLUT_STROKE_ROMAN, SPACE_CHAR );
93 }
94 
95 //Check whether we need to recalc the metrics, and do it in const object.
96 void Font::calcMetricsIfNeeded( void ) const
97 {
98  if (m_needMetrics) {
99  //calcmetrics is a cache. Doesn't change the "real" state of the object.
100  Font *s = const_cast< Font* > (this);
101  s->calcMetrics();
102  }
103 }
104 
105 //Draw a character.
106 float Font::drawChar( char c ) const
107 {
109  if ( useStroke() ) {
110  glutStrokeCharacter( GLUT_STROKE_ROMAN, c );
111  if (c == SPACE_CHAR)
112  //Need to translate back a bit -- the width of the space is too big.
113  glTranslated( m_spaceCharFixup, 0.0, 0.0 );
114  else
115  glTranslated( m_extraCharWidth, 0.0, 0.0 );
116  return 0;
117  } else {
118  glutBitmapCharacter( GLUT_BITMAP_HELVETICA_12, c );
119  return glutBitmapWidth( GLUT_BITMAP_HELVETICA_12, c );
120  }
121 }
122 
123 //The width of a character in reference units.
124 double Font::charWidth( char c ) const
125 {
127  if ( useStroke() ) {
128  if (c == SPACE_CHAR) {
129  //Spaces have a special width.
130  const double spaceCharWidth =
131  glutStrokeWidth( GLUT_STROKE_ROMAN, SPACE_CHAR )+m_spaceCharFixup;
132  return spaceCharWidth+GLUT_WIDTH_HACK;
133  }
134  const double charWidth = glutStrokeWidth( GLUT_STROKE_ROMAN, c );
135  return charWidth+m_extraCharWidth+GLUT_WIDTH_HACK;
136  } else {
137  return glutBitmapWidth( GLUT_BITMAP_HELVETICA_12, c )/(size()*2);
138  }
139 }
140 
141 //The width of a string in reference units.
142 double Font::stringWidth( const std::string &str ) const
143 {
145 
146  double result = 0.0;
147  for (string::const_iterator i = str.begin(); i != str.end(); i++)
148  result += charWidth( *i );
149  return result;
150 }
151 
152 //Calculate the OpenGL stroke width for a font size+weight.
153 //This value is cached in the font object.
154 double Font::strokeWidth( void ) const
155 {
157 
158  return m_strokeWidth;
159 }
160 
161 //Vertical scaling factor to be used to image this font.
162 double Font::verticalScaling( void ) const
163 {
165 
166  return m_verticalScaling;
167 }
168 
169 //Horizontal scaling factor to be used to image this font.
170 double Font::horizontalScaling( void ) const
171 {
173 
174  return m_horizontalScaling;
175 }
176