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
painttext.h
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 #ifndef __PAINTTEXT_H__
23 #define __PAINTTEXT_H__
24 
25 #include <string>
26 #include "guidefs.h"
27 #include "font.h"
28 
29 //See cpp file for detailed descriptions of classes, functions, etc.
30 
31 //This class is used to draw text in a rectangle. It is not a Control, just a
32 //repository of text attributes and behavior. The line spacing is the same as the
33 //Font size. Multi-line text starts at the top-left of the rectangle, and continues
34 //for as many lines a necessary. Single-line text is centered vertically, and an
35 //ellipsis is added at the end of the visible text if the text must be clipped to
36 //fit in the rectangle.
37 //This object can be used to calculate, say, the bounding box of some text without
38 //needing to actually draw it.
39 //This class supports a simple language embedded in the text that can be used to
40 //change some attributes fo sections of text.
41 
42 //This class allows a number of formatting characters. Here are the rules:
43 //-- The formatting char is "#".
44 //-- Format commands are indicated by a single character, which is case-sensitive.
45 //-- The results of errors in the formatting commands is not defined.
46 //-- Commands can take no parameter, a required param, or an optional param.
47 //-- Commands that take parameters always end with another "#".
48 //-- Some kinds of format state are pushed onto a stack. You can pop the stack back
49 //to the previous value, or reset to the original value.
50 //##: One "#". "This is door ##3."
51 //#n[line-space]#: Break a line here. Optional floating-point parameter which is the
52 //line spacing between the current line and the next line only. (This doesn't
53 //affect line spacing after the current line.)
54 //0.0, for instance, would results in overwriting the same line, 2.0 is double-space.
55 //"First line.#n#Second line." "Double space#n2#line#n#line 2".
56 //#l<line-spacing>#: Set the amount of space between lines. Parameter is not optional.
57 //This command does not break the line, it just sets the line spacing for the
58 //following lines. There isn't a stack associated with this setting.
59 //#b[stroke-weight]#: "Bold". "Push" the font stroke weight. Parameter has same semantics
60 //as Font object -- floating-point. Default stroke weight is BOLD_STROKE.
61 //"#b#Price:#-b $50,000" "I must #b4.5#emphasize#!b this."
62 //#c<color-spec>#: "Push" a new text color (doesn't change the background color).
63 //Specify R, then B, G, A as floating-point values between 0 and 1.0 (same spec as
64 //GFXColor). The value are separated by ":", and A is optional. Default for A
65 //is 1.0.
66 //"This is #c1:0:0#red#-c."
67 //#-{bc}: "Pop" a font/color off the appropriate stack. Restores previous value.
68 //See font and color examples above.
69 //#!{bc}: "Reset" font/color to the original version. Same parameters as "#-".
70 
71 //Helper function. Pass in RGB values, get out a color command string for those values.
72 std::string colorsToCommandString( float r, float g, float b, float a = 1.0 );
73 
74 //Class.
75 class PaintText
76 {
77 public:
78 //The outside boundaries to use for drawing.
79  virtual void setRect( const Rect &r );
80  virtual Rect rect( void ) const
81  {
82  return m_rect;
83  }
84 
85 //The text to draw.
86  virtual void setText( const std::string &text );
87  virtual const std::string& text( void ) const
88  {
89  return m_text;
90  }
91 
92 //The initial color of the text.
93  virtual void setColor( const GFXColor &c );
94  virtual GFXColor color( void ) const
95  {
96  return m_color;
97  }
98 
99 //The initial Font for text.
100  virtual void setFont( const Font &f );
101  virtual Font font( void ) const
102  {
103  return m_font;
104  }
105 
106 //Text justification.
107  virtual void setJustification( Justification j );
108  virtual Justification justification( void ) const
109  {
110  return m_justification;
111  }
112 
113 //What to do when text width exceeds boundary rectangle.
115  {
116  FULL_WIDTH, //Do nothing. Just do one line of text.
117  ELLIPSIS, //Put an ellipsis at the end of the text.
118  MULTI_LINE //Go to the next line.
119  };
120 
121 //What to do when text width exceeds boundary rectangle.
122  virtual void setWidthExceeded( WidthExceeded w );
123  virtual WidthExceeded widthExceeded( void ) const
124  {
125  return m_widthExceeded;
126  }
127 
128 //How many lines are in the current layout.
129  virtual int lineCount( void ) const;
130 
131 //How many lines would be painted in a vertical interval.
132  virtual int visibleLineCountStartingWith( int lineNumber, float vertInterval ) const;
133 
134 //Layout version. This is used to tell whether the layout has changed.
135  virtual int layoutVersion( void ) const;
136 
137 //Draw the text.
138  static const size_t END_LINE;
139  virtual void drawLines( size_t start, size_t count = END_LINE ) const;
140  void draw( void ) const
141  {
142  drawLines( 0 );
143  }
144 
145 //CONSTRUCTION
146 public: PaintText( void );
147  PaintText( const Rect &rect,
148  const std::string &text,
149  const Font &font,
150  const GFXColor &color,
152  WidthExceeded w = ELLIPSIS );
153  virtual ~PaintText( void ) {}
154 
155 protected:
156 //INTERNAL IMPLEMENTATION
157 
158 //Use the current attributes to create a display list for the text.
159 //This does the real work, and doesn't check whether it needs to be done.
160  void calcLayout( void );
161 
162 //Check whether we need to recalc the layout, and do it in const object.
163  void calcLayoutIfNeeded( void ) const;
164 
165 //Description of a "fragment" of text to be displayed.
166 //This is a section of text with the same attributes.
168  {
169  size_t start; //Index (in m_text) of first character in the fragment.
170  size_t end; //Index of last character in fragment (NOT one past last char).
171  Font font; //Font.
172  GFXColor color; //Text color.
173  };
174 
175 //Layout of one line.
176  struct TextLine
177  {
178  float height; //Height of this line.
179  float width; //Width of all the chars in this line (including ellipsis).
180  float x; //x-origin of first character, relative to boundary rect.
181  float baseLine; //y-origin of first character, relative to top of line.
182  vector< TextFragment >fragments; //Bits of text that make up this line.
183  };
184 
185 //The state used to calculate the layout.
186  struct LayoutState
187  {
188  vector< GFXColor >colorStack; //Color stack.
189  vector< Font > fontStack; //Font stack.
190  float currentLineSpacing; //Line spacing for the current line.
191  float permanentLineSpacing; //New permanent line spacing.
192 
193  //CONSTRUCTION.
194  LayoutState( float lineSpacing = 0.0, float permSpacing = 0.0 ) :
195  currentLineSpacing( lineSpacing )
196  , permanentLineSpacing( permSpacing )
197  {}
198  };
199 
200 //The x-origin of a line. Horizontal starting position.
201  float lineInset( const TextLine &line );
202 
203 //Create a fragment for the next substring of characters that fits in the specified width.
204 //The fragment is added to the specified TextLine.
205 //Formatting commands should have been filtered out already.
206  void addFragment( TextLine &line, //Line descriptor.
207  const std::string::size_type endPos, //One past last char to consider.
208  std::string::size_type &startPos, //IN/OUT: location of string.
209  double &width //IN/OUT: Reference width of string.
210  );
211 
212 //Parse a format string in a PaintText string.
213 //The first character should be the one *after* the initial format char.
214  void parseFormat( std::string::size_type startPos, //Location of beginning of string to examine.
215  std::string::size_type *resultPos, //OUT: Ptr to string past the format string.
216  bool *endLine //OUT: True = Done with current line.
217  );
218 
219 //Parse one line of text, create fragments, end line when overflow width.
220  void parseFragmentsWithCharBreak( TextLine &line, //Line descriptor.
221  std::string::size_type startPos, //Location of beginning of string to examine.
222  std::string::size_type endPos, //Location of one past the last character to examine.
223  float maxWidth, //Can't go beyond this width.
224  bool ellipsis, //True = if line doesn't fit, append ellipsis.
225  std::string::size_type *resultPos //OUT: Ptr to string past the format string.
226  );
227 
228 //Parse one line of text, create fragments, end line on word break when width overflows.
229  void parseFragmentsWithWordBreak( TextLine &line, //Line descriptor.
230  std::string::size_type startPos, //Location of beginning of string to examine.
231  float maxWidth, //Can't go beyond this width.
232  std::string::size_type *resultPos //OUT: Ptr to string past the format string.
233  );
234 
235 //VARIABLES
236 protected:
237  Rect m_rect; //Boundary rectangle.
238  std::string m_text; //Text to draw.
239  GFXColor m_color; //Initial color.
240  Font m_font; //Initial font.
241  Justification m_justification; //Right, center, left.
242  WidthExceeded m_widthExceeded; //What to do when text width exceeds boundary rectangle.
243 
244  bool m_needLayout; //True = something changed. Need to recalc the layout.
245  int m_layoutVersion; //Incremented every time we re-layout things.
246  vector< TextLine >m_lines; //List of lines.
247  double m_verticalScaling; //Vertical factor from char reference space to identity space.
248  double m_horizontalScaling; //Horizontal factor from char reference space to identity space.
249  LayoutState m_layout; //Shared state for layout operation.
250 };
251 
252 #endif //__PAINTTEXT_H__
253