Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

dll/drawstring.c

Go to the documentation of this file.
00001 /* {{{
00002  * CalcRogue, a roguelike game for PCs, calculators and PDAs
00003  * Copyright (C) 2003 Jim Babcock
00004  * 
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * }}} */
00019 // drawstring.c
00028 
00029 #include "crogue.h"
00030 #include "dll.h"
00031 
00032 //{{{
00033 static int StringWidth(const char *str)
00034 {
00035     uint len=0;
00036     
00037     while(*str != '\0') {
00038         len += FontWidth(*str);
00039         str++;
00040     }
00041     
00042     return len;
00043 }
00044 //}}}
00045 
00046 //{{{
00047 void clear_string(int x, int y, int width, int height)
00048 {
00049     Graph_ClearRect(x, y, x+width-1, y+height*FontHeight()-1);
00050 }
00051 //}}}
00052 
00053 static int numTabStops = 1;
00054 static uchar tabStops[16]={0};
00055 
00056 //{{{
00057 void setTabStops(int num, ...)
00058 {
00059     va_list varargs;
00060     int i;
00061     numTabStops = num;
00062     
00063     va_start(varargs, num);
00064     for(i=0; i<num; i++)
00065         tabStops[i] = va_arg(varargs, int);
00066     va_end(varargs);
00067 }
00068 //}}}
00069 //{{{
00070 static int findTab(int pos)
00071 {
00072     int i;
00073     for(i=0; i<numTabStops; i++)
00074     {
00075         if(tabStops[i] > pos)
00076             return tabStops[i];
00077     }
00078     return SCREEN_WIDTH * 2;
00079 }
00080 //}}}
00081 
00082 /*
00083  * height=0 means no wrapping allowed; instead, clip the right edge (don't
00084  * pause, either)
00085  * Tab stops are given as distance from x, not from the left edge of the screen
00086  * Rows are in textual lines; width, x, and y are in pixels.
00087  */
00088 //{{{
00089 void draw_string(const char *string, draw_string_info *start_state, short x, short y, short width, short height, short wrap)
00090 {
00091     int i, ii;
00092     int curX=0;
00093     int tempX;
00094     int curRow=0;
00095     int maxWidth;
00096     int rows = height/FontHeight();
00097     
00098     if(start_state)
00099     {
00100         curX = start_state->curX;
00101         curRow = start_state->curRow;
00102     }
00103     
00104     tempX = curX;
00105     
00106     i=0;
00107     
00108     while( string[i] != '\0' )
00109     {
00110         maxWidth = width;
00111         if( wrap && curRow+1 == rows )
00112             maxWidth -= StringWidth(gettext(" -More-"));
00113         
00114         if( string[i] == '\t' )
00115         {
00116             if(findTab(tempX) > maxWidth)
00117                 goto startNewLine;
00118             else
00119                 tempX = findTab(tempX);
00120         }
00121         else
00122         {
00123             tempX += FontWidth(string[i]);
00124         }
00125         
00126         // If past the end of the line
00127         if(tempX >= maxWidth || string[i] == '\n') {
00128 startNewLine:
00129             if(!wrap)
00130                 break;
00131             
00132             if(string[i] != '\n' && string[i] != '\t')
00133             {
00134                 // Back up until (a) it fits and (b) it isn't in the middle of a word
00135                 while(i >= 0 && string[i] != ' ' && tempX>0)
00136                     tempX -= FontWidth(string[i--]);
00137                 if(tempX<=0) // Overshot; this line needs to be broken on a non-word-break
00138                 {
00139                     while(tempX<=maxWidth)
00140                         tempX += FontWidth(string[++i]);
00141                     tempX -= FontWidth(string[--i]);
00142                 }
00143             }
00144             
00145             // Print it out
00146             for(ii=0; ii<i; ii++) {
00147                 if(string[ii]!='\t')
00148                     Graph_DrawChar(x+curX, y + curRow*FontHeight(), string[ii]);
00149                 if(string[ii]=='\t')
00150                     curX = findTab(curX);
00151                 else
00152                     curX += FontWidth(string[ii]);
00153             }
00154             
00155             // If out of lines, print the -More- prompt
00156             if( curRow+1 == rows ) {
00157                 Graph_DrawStr(curX+x, curRow*FontHeight() + y, gettext(" -More-"));
00158                 read_char();
00159                 clear_string(x, y, width, rows);
00160                 
00161                 curRow = -1;
00162                 curX = tempX = 0;
00163             }
00164             
00165             string += i;
00166             string++;
00167             
00168             i=0;
00169             
00170             curRow++;
00171             curX = tempX = 0;
00172         } else {
00173             i++;
00174         }
00175     }
00176     
00177     // Print the remainder
00178     for( i=0; string[i]!='\0'; i++ ) {
00179         if(string[i] == '\t')
00180         {
00181             curX = findTab(curX);
00182             continue;
00183         }
00184         Graph_DrawChar( x+curX, y + curRow*FontHeight(), string[i]);
00185         curX += FontWidth( string[i] );
00186     }
00187     
00188     if(start_state)
00189     {
00190         start_state->curX = curX;
00191         start_state->curRow = curRow;
00192     }
00193 }
00194 //}}}

Generated on Thu May 20 13:12:09 2004 for CalcRogue by doxygen 1.3.6