   Nice code for word wrap text [ SRC  FREE ]
  I needed word wrap and text color coding in my game, so i came up with this code - in pascal/delphi but i guess it is easy to translate to anything you prefer to use. before using it you need to switch to "2D mode" using something this: http://www.gamedev.net/community/forums/topic.asp?topic_id=104791  I'd also like to see your solutions to this problem. // simple helper func - converts opengl 2d coords to windows-like coordsprocedure glvertex2fwin(const x, y: single);begin  glvertex2f(x, win_height - y);end;procedure DrawFont(x, y, mx, my, trans: single; const Text: string;  fontn, wordwrap: integer);var  i: integer;  b: byte;  cw: integer;  ta, tb, tc, td: single;  va, vb, vc, vd: single;  // current left edge  L: single;  // skip this much of characters from being parsed  SK: integer;  wraps: array[0..31] of word;  // i dont think my game will ever need / have more than 32 word wraps  maxwrap: integer;  currwrap: integer;  lastspace: integer; // faster word wrap  procedure Vwrap(c: integer);  begin    cw := 0;    wraps[maxwrap] := c;    maxwrap := maxwrap + 1;    // since there is no array bounds checking this takes care for safety    if maxwrap > high(wraps) then maxwrap := high(wraps);  end;  // this function processes the string and remembers all locations where lines should wrap (line returns, word wraps, etc..)  procedure MeasureWraps;  var    i: integer;  begin    maxwrap := 0;    lastspace := -1; // faster word wrap    for i := 0 to length(Text) dobegin if SK <> 0 then  begin    SK := SK - 1;    continue;  end; // skipping text coding characters b := byte(Text); <span class="cpp-comment">// we need a integer type to use for array access,</span> <span class="cpp-keyword">if</span> b = <span class="cpp-number">32</span> then lastspace := i; <span class="cpp-comment">// remember last space for word wrapping</span> <span class="cpp-keyword">if</span> b = <span class="cpp-number">126</span> then  begin    sk := <span class="cpp-number">2</span>;    <span class="cpp-keyword">continue</span>;  end;  <span class="cpp-comment">// skip ~X~ color coding keyword</span> <span class="cpp-comment">// next character would fall over the specified text width dimension, wrap at last known space character</span> <span class="cpp-keyword">if</span> (wordwrap &lt;&gt; <span class="cpp-number">0</span>) and (cw + trunc(FontGeo[fontn, b].spacing * mx) &gt; wordwrap) then  begin   Vwrap(lastspace);    <span class="cpp-keyword">continue</span>; end; <span class="cpp-keyword">if</span> b = <span class="cpp-number">13</span> then  begin    Vwrap(i);    <span class="cpp-keyword">continue</span>;  end; <span class="cpp-comment">// return character - go to new line</span> <span class="cpp-comment">// add character width to this line text width</span> cw := cw + trunc(FontGeo[fontn, b].spacing * mx);    end;  end;  <span class="cpp-comment">// go to next line</span>  procedure wrap;  begin    cw := <span class="cpp-number">0</span>;    L := L + (FontGeo[fontn, <span class="cpp-number">32</span>].H * my);  end;  <span class="cpp-comment">// process color codes</span>  procedure EatColor; <span class="cpp-comment">// changes font color depending on keyword</span>  begin    <span class="cpp-keyword">if</span> Text = 'W' then glcolor4f(<span class="cpp-number">1</span>, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, trans); <span class="cpp-comment">// white</span>    <span class="cpp-keyword">if</span> Text = 'N' then glcolor4f(<span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, trans); <span class="cpp-comment">// none - black</span>    <span class="cpp-keyword">if</span> Text = 'R' then glcolor4f(<span class="cpp-number">0</span>.<span class="cpp-number">9</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>, trans); <span class="cpp-comment">// red</span>    <span class="cpp-keyword">if</span> Text = 'G' then glcolor4f(<span class="cpp-number">0</span>, <span class="cpp-number">0</span>.<span class="cpp-number">9</span>, <span class="cpp-number">0</span>, trans); <span class="cpp-comment">// green</span>    <span class="cpp-keyword">if</span> Text = 'B' then glcolor4f(<span class="cpp-number">0</span>, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>.<span class="cpp-number">9</span>, trans); <span class="cpp-comment">// blue</span>    <span class="cpp-keyword">if</span> Text = 'Y' then glcolor4f(<span class="cpp-number">1</span>.<span class="cpp-number">0</span>, <span class="cpp-number">1</span>, <span class="cpp-number">0</span>, trans); <span class="cpp-comment">// yellow</span>    <span class="cpp-keyword">if</span> Text = 'T' then glcolor4f(<span class="cpp-number">0</span>, <span class="cpp-number">1</span>, <span class="cpp-number">1</span>, trans); <span class="cpp-comment">// teal</span>    <span class="cpp-keyword">if</span> Text = 'O' then glcolor4f(<span class="cpp-number">1</span>, <span class="cpp-number">0</span>.<span class="cpp-number">7734375</span>, <span class="cpp-number">0</span>.<span class="cpp-number">09765625</span>, trans); <span class="cpp-comment">// orange</span>    SK := <span class="cpp-number">2</span>; <span class="cpp-comment">// skip 2 chars so the color coding is like '~C~' where C is color</span>  end;begin  <span class="cpp-keyword">if</span> length(Text) = <span class="cpp-number">0</span> then exit; <span class="cpp-comment">// idiot proof fuse</span>  <span class="cpp-comment">// ensure variables are reset for preprocessing</span>  cw := <span class="cpp-number">0</span>;  SK := <span class="cpp-number">0</span>;  fillchar(wraps, <span class="cpp-keyword">sizeof</span>(wraps), $FF);  MeasureWraps;  <span class="cpp-comment">// ensure variables are reset for rendering</span>  cw := <span class="cpp-number">0</span>;  L := <span class="cpp-number">0</span>;  SK := <span class="cpp-number">0</span>;  currwrap := <span class="cpp-number">0</span>;  glBindTexture(GL_TEXTURE_2D, Font.tex[fontn].GLID);  glBegin(GL_quads);  <span class="cpp-keyword">for</span> i := <span class="cpp-number">0</span> to length(Text) <span class="cpp-keyword">do</span>   begin    <span class="cpp-keyword">if</span> SK &lt;&gt; <span class="cpp-number">0</span> thenbegin  SK := SK - <span class="cpp-number">1</span>;  <span class="cpp-keyword">continue</span>;end;    b := byte(Text); <span class="cpp-comment">// we need a integer type to use for array access</span>    <span class="cpp-keyword">if</span> b = <span class="cpp-number">126</span> thenbegin  eatcolor;  <span class="cpp-keyword">continue</span>;end;    <span class="cpp-comment">// find out if we are supposed to wrap at this character</span>    <span class="cpp-keyword">if</span> currwrap &lt; maxwrap then <span class="cpp-keyword">if</span> wraps[currwrap] = i then  begin    wrap;    currwrap := currwrap + <span class="cpp-number">1</span>;    <span class="cpp-keyword">continue</span>;  end;    <span class="cpp-comment">// get tex coords from array</span>    ta := FontGeo[fontn, b].X / <span class="cpp-number">256</span>;    tb := FontGeo[fontn, b].X / <span class="cpp-number">256</span> + FontGeo[fontn, b].W / <span class="cpp-number">256</span>;    tc := FontGeo[fontn, b].Y / <span class="cpp-number">256</span>;    td := FontGeo[fontn, b].Y / <span class="cpp-number">256</span> + FontGeo[fontn, b].H / <span class="cpp-number">256</span>;    <span class="cpp-comment">// build vertices</span>    va := cw;  <span class="cpp-comment">// top left</span>    vb := va + (FontGeo[fontn, b].W * mx);<span class="cpp-comment">// top right</span>    vc := (FontGeo[fontn, b].YOFS * my) + L;  <span class="cpp-comment">// bottom left</span>    vd := vc + (FontGeo[fontn, b].H * my);<span class="cpp-comment">// bottom right</span>    <span class="cpp-comment">// crunch</span>    gltexcoord2f(ta, tc);glvertex2fwin(x + va, y + vc);    gltexcoord2f(ta, td);glvertex2fwin(x + va, y + vd);    gltexcoord2f(tb, td);glvertex2fwin(x + vb, y + vd);    gltexcoord2f(tb, tc);glvertex2fwin(x + vb, y + vc);    <span class="cpp-comment">// add character size to left edge</span>    cw := cw + trunc(FontGeo[fontn, b].spacing * mx);  end;  glend;end;</pre></div><!–ENDSCRIPT–> 
  man is this ever useful. ive spent days trying to implement wordwrap, giving up and then just reverting back to the good ole' char wrap muahaha   