[nexuiz-commits] r8546 - in trunk/data: . qcsrc/client qcsrc/common qcsrc/menu qcsrc/menu/item qcsrc/menu/nexuiz qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Jan 24 16:44:44 EST 2010


Author: blub0
Date: 2010-01-24 16:44:44 -0500 (Sun, 24 Jan 2010)
New Revision: 8546

Modified:
   trunk/data/defaultNexuiz.cfg
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/csqc_builtins.qc
   trunk/data/qcsrc/client/mapvoting.qc
   trunk/data/qcsrc/client/miscfunctions.qc
   trunk/data/qcsrc/client/sbar.qc
   trunk/data/qcsrc/common/gamecommand.qc
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/menu/draw.qc
   trunk/data/qcsrc/menu/draw.qh
   trunk/data/qcsrc/menu/item/inputbox.c
   trunk/data/qcsrc/menu/item/label.c
   trunk/data/qcsrc/menu/mbuiltin.qh
   trunk/data/qcsrc/menu/menu.qc
   trunk/data/qcsrc/menu/nexuiz/campaign.c
   trunk/data/qcsrc/menu/nexuiz/charmap.c
   trunk/data/qcsrc/menu/nexuiz/cvarlist.c
   trunk/data/qcsrc/menu/nexuiz/demolist.c
   trunk/data/qcsrc/menu/nexuiz/keybinder.c
   trunk/data/qcsrc/menu/nexuiz/maplist.c
   trunk/data/qcsrc/menu/nexuiz/playerlist.c
   trunk/data/qcsrc/menu/nexuiz/serverlist.c
   trunk/data/qcsrc/menu/nexuiz/skinlist.c
   trunk/data/qcsrc/menu/nexuiz/util.qc
   trunk/data/qcsrc/server/cl_player.qc
   trunk/data/quake.rc
Log:
committing stringwidth change - from now on, always provide a fontsize argument to text-handlng functions

Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/defaultNexuiz.cfg	2010-01-24 21:44:44 UTC (rev 8546)
@@ -1286,13 +1286,6 @@
 set menu_slowmo 1
 seta menu_sounds 0 "enables menu sound effects. 1 enables click sounds, 2 also enables hover sounds"
 
-// loadfont console     gfx/vera-mono
-// loadfont sbar        gfx/vera-mono
-loadfont notify      gfx/vera-sans
-loadfont chat        gfx/vera-sans
-// loadfont centerprint gfx/vera-mono
-// loadfont infobar     gfx/vera-mono
-loadfont user0       gfx/vera-sans
 r_textbrightness 0.2
 r_textcontrast 0.8
 r_textshadow 1
@@ -1437,9 +1430,10 @@
 seta sbar_fontsize_spec 16
 seta scr_centersize 11
 seta sbar_width 560
-alias sbar_font "loadfont user1 $*; loadfont user2 ${*}-big; sbar_columns_set"
+// alias sbar_font "loadfont user1 ${1},gfx/fallback ${2-}; loadfont user2 ${1}-big ${2-}; sbar_columns_set"
+alias sbar_font "set _requested_sbar_font \"${*}\""
 seta sbar_columns default
-sbar_font gfx/vera-sans
+sbar_font gfx/vera-sans 8 12 16 24 32
 seta sbar_showbinds 1	"display actions / bound keys in the strings shown during the game. 0 displays only actions, 1 displays only bound keys, 2 displays both"
 seta sbar_showbinds_limit 2	"maximum number of bound keys to show for an action. 0 for unlimited"
 

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/client/Main.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -444,7 +444,7 @@
 	coord2d_topleft = project_3d_to_2d(self.origin + view_up * 4 - view_right * 4);
 	coord2d_topright = project_3d_to_2d(self.origin + view_up * 4 + view_right * 4);
 
-	fs = '1 1 0' * ((coord2d_topright_x - coord2d_topleft_x) / stringwidth(s, FALSE));
+	fs = '1 1 0' * ((coord2d_topright_x - coord2d_topleft_x) / stringwidth(s, FALSE, '8 8 0'));
 
 	coord2d = coord2d_topleft;
 	if(fs_x < 8)

Modified: trunk/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_builtins.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/client/csqc_builtins.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -98,7 +98,7 @@
 void	drawsetcliparea(float x, float y, float width, float height) = #324;
 void	drawresetcliparea(void) = #325;
 float	drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #326;
-float	stringwidth(string text, float handleColors) = #327;
+float	stringwidth(string text, float handleColors, vector fontSize) = #327;
 float	drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) = #328;
 
 

Modified: trunk/data/qcsrc/client/mapvoting.qc
===================================================================
--- trunk/data/qcsrc/client/mapvoting.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/client/mapvoting.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -13,7 +13,7 @@
 float mv_timeout;
 float mv_maps_mask;
 
-string MapVote_FormatMapItem(float id, string map, float count, float maxwidth)
+string MapVote_FormatMapItem(float id, string map, float count, float maxwidth, vector fontsize)
 {
 	string pre, post;
 	pre = strcat(ftos(id+1), ". ");
@@ -26,8 +26,8 @@
 	}
 	else
 		post = "";
-	maxwidth -= stringwidth(pre, FALSE) + stringwidth(post, FALSE);
-	map = textShortenToWidth(map, maxwidth, stringwidth_nocolors);
+	maxwidth -= stringwidth(pre, FALSE, fontsize) + stringwidth(post, FALSE, fontsize);
+	map = textShortenToWidth(map, maxwidth, fontsize, stringwidth_nocolors);
 	return strcat(pre, map, post);
 }
 
@@ -56,9 +56,9 @@
 	drawfont = sbar_font;
 	pos_y = pos_y + img_size_y;
 	
-	label = MapVote_FormatMapItem(id, map, count, tsize / sbar_fontsize_x);
+	label = MapVote_FormatMapItem(id, map, count, tsize, sbar_fontsize);
 
-	text_size = stringwidth(label, false) * sbar_fontsize_x;
+	text_size = stringwidth(label, false, sbar_fontsize);
 	
 	pos_x -= text_size*0.5;
 	drawstring(pos, label, sbar_fontsize, rgb, 1, DRAWFLAG_NORMAL);
@@ -102,9 +102,9 @@
 	drawfont = sbar_font;
 	pos_y = pos_y + sbar_fontsize_y;
 	
-	label = MapVote_FormatMapItem(id, "Don't care", count, tsize / sbar_fontsize_x);
+	label = MapVote_FormatMapItem(id, "Don't care", count, tsize, sbar_fontsize);
 
-	text_size = stringwidth(label, false) * sbar_fontsize_x;
+	text_size = stringwidth(label, false, sbar_fontsize);
 	
 	pos_x -= text_size*0.5;
 	drawstring(pos, label, sbar_fontsize, rgb, 1, DRAWFLAG_NORMAL);
@@ -149,13 +149,15 @@
 
 	pos_y = ymin;
 	pos_z = 0;
-	pos_x = center - stringwidth("Vote for a map", false) * 0.5 * 24;
+	//pos_x = center - stringwidth("Vote for a map", false) * 0.5 * 24;
+	pos_x = center - stringwidth("Vote for a map", false, '12 0 0');
 	drawstring(pos, "Vote for a map", '24 24 0', '1 1 1', 1, DRAWFLAG_NORMAL);
 	pos_y += 26;
 
 	i = ceil(max(0, mv_timeout - time));
 	map = strcat(ftos(i), " seconds left");
-	pos_x = center - stringwidth(map, false) * 0.5 * 16;
+	//pos_x = center - stringwidth(map, false) * 0.5 * 16;
+	pos_x = center - stringwidth(map, false, '8 0 0');
 	drawstring(pos, map, '16 16 0', '0 1 0', 1, DRAWFLAG_NORMAL);
 	pos_y += 22;
 	pos_x = xmin;

Modified: trunk/data/qcsrc/client/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/client/miscfunctions.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/client/miscfunctions.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -1,4 +1,4 @@
-var float(string text, float handleColors) stringwidth;
+var float(string text, float handleColors, vector fontSize) stringwidth;
 
 entity players;
 entity teams;
@@ -449,7 +449,7 @@
 	else
 		drawfontscale = '1 1 0';
 	dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
-	drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE) / drawfontscale_x), text, scale * (sz / drawfontscale_x), rgb, alpha * (1 - fadelerp), flag);
+	drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE, '1 0 0') / drawfontscale_x), text, scale * sz, rgb, alpha * (1 - fadelerp), flag);
 	if(cvar("menu_font_size_snapping_fix"))
 		drawfontscale = '1 1 0';
 }
@@ -460,5 +460,5 @@
 	sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
 
 	dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
-	drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, TRUE)), text, scale * sz, alpha * (1 - fadelerp), flag);
+	drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, TRUE, '1 0 0')), text, scale * sz, alpha * (1 - fadelerp), flag);
 }

Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/client/sbar.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -503,7 +503,6 @@
 {
 	float i, j, slash;
 	string str, pattern;
-	float digit;
 	float have_name, have_primary, have_secondary, have_separator;
 	float missing;
 
@@ -540,7 +539,6 @@
 	sbar_num_fields = 0;
 
 	drawfont = sbar_font;
-	digit = stringwidth("0123456789", FALSE) / 10;
 
 	for(i = 0; i < argc - 1; ++i)
 	{
@@ -566,7 +564,7 @@
 
 		strunzone(sbar_title[sbar_num_fields]);
 		sbar_title[sbar_num_fields] = strzone(str);
-		sbar_size[sbar_num_fields] = stringwidth(str, FALSE);
+		sbar_size[sbar_num_fields] = stringwidth(str, FALSE, sbar_fontsize);
 		str = strtolower(str);
 
 		if(str == "ping") {
@@ -643,7 +641,7 @@
 				}
 				sbar_title[1] = strzone("|");
 				sbar_field[1] = SP_SEPARATOR;
-				sbar_size[1] = stringwidth("|", FALSE);
+				sbar_size[1] = stringwidth("|", FALSE, sbar_fontsize);
 				++sbar_num_fields;
 				print("fixed missing field '|'\n");
 			}
@@ -652,7 +650,7 @@
 		{
 			strunzone(sbar_title[sbar_num_fields]);
 			sbar_title[sbar_num_fields] = strzone("|");
-			sbar_size[sbar_num_fields] = stringwidth("|", FALSE);
+			sbar_size[sbar_num_fields] = stringwidth("|", FALSE, sbar_fontsize);
 			sbar_field[sbar_num_fields] = SP_SEPARATOR;
 			++sbar_num_fields;
 			print("fixed missing field '|'\n");
@@ -661,7 +659,7 @@
 		{
 			strunzone(sbar_title[sbar_num_fields]);
 			sbar_title[sbar_num_fields] = strzone(scores_label[ps_secondary]);
-			sbar_size[sbar_num_fields] = stringwidth(sbar_title[sbar_num_fields], FALSE);
+			sbar_size[sbar_num_fields] = stringwidth(sbar_title[sbar_num_fields], FALSE, sbar_fontsize);
 			sbar_field[sbar_num_fields] = ps_secondary;
 			++sbar_num_fields;
 			print("fixed missing field '", scores_label[ps_secondary], "'\n");
@@ -670,7 +668,7 @@
 		{
 			strunzone(sbar_title[sbar_num_fields]);
 			sbar_title[sbar_num_fields] = strzone(scores_label[ps_primary]);
-			sbar_size[sbar_num_fields] = stringwidth(sbar_title[sbar_num_fields], FALSE);
+			sbar_size[sbar_num_fields] = stringwidth(sbar_title[sbar_num_fields], FALSE, sbar_fontsize);
 			sbar_field[sbar_num_fields] = ps_primary;
 			++sbar_num_fields;
 			print("fixed missing field '", scores_label[ps_primary], "'\n");
@@ -792,14 +790,14 @@
 float sbar_fixscoreboardcolumnwidth_iconlen;
 float sbar_fixscoreboardcolumnwidth_marginlen;
 
-float stringwidth_colors(string s)
+float stringwidth_colors(string s, vector theSize)
 {
-	return stringwidth(s, TRUE);
+	return stringwidth(s, TRUE, theSize);
 }
 
-float stringwidth_nocolors(string s)
+float stringwidth_nocolors(string s, vector theSize)
 {
-	return stringwidth(s, FALSE);
+	return stringwidth(s, FALSE, theSize);
 }
 
 string Sbar_FixScoreboardColumnWidth(float i, string str)
@@ -837,14 +835,14 @@
 	sbar_fixscoreboardcolumnwidth_iconlen *= sbar_fontsize_y / sbar_fontsize_x; // fix icon aspect
 
 	if(sbar_fixscoreboardcolumnwidth_iconlen != 0)
-		sbar_fixscoreboardcolumnwidth_marginlen = stringwidth(" ", FALSE);
+		sbar_fixscoreboardcolumnwidth_marginlen = stringwidth(" ", FALSE, sbar_fontsize);
 	else
 		sbar_fixscoreboardcolumnwidth_marginlen = 0;
 
 	if(field == SP_NAME) // name gets all remaining space
 	{
 		float namesize, j;
-		namesize = sbwidth / sbar_fontsize_x;
+		namesize = sbwidth;// / sbar_fontsize_x;
 		for(j = 0; j < sbar_num_fields; ++j)
 			if(j != i)
 				if (sbar_field[i] != SP_SEPARATOR)
@@ -854,11 +852,11 @@
 		
 		if (sbar_fixscoreboardcolumnwidth_iconlen != 0)
 			namesize -= sbar_fixscoreboardcolumnwidth_marginlen + sbar_fixscoreboardcolumnwidth_iconlen;
-		str = textShortenToWidth(str, namesize, stringwidth_colors);
-		sbar_fixscoreboardcolumnwidth_len = stringwidth(str, TRUE);
+		str = textShortenToWidth(str, namesize, sbar_fontsize, stringwidth_colors);
+		sbar_fixscoreboardcolumnwidth_len = stringwidth(str, TRUE, sbar_fontsize);
 	}
 	else
-		sbar_fixscoreboardcolumnwidth_len = stringwidth(str, FALSE);
+		sbar_fixscoreboardcolumnwidth_len = stringwidth(str, FALSE, sbar_fontsize);
 	
 	f = sbar_fixscoreboardcolumnwidth_len + sbar_fixscoreboardcolumnwidth_marginlen + sbar_fixscoreboardcolumnwidth_iconlen;
 	if(sbar_size[i] < f)
@@ -901,29 +899,29 @@
 			break;
 
 		if(is_spec && field != SP_NAME && field != SP_PING) {
-			pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+			pos_x += sbar_size[i] + sbar_fontsize_x;
 			continue;
 		}
 		str = Sbar_GetField(pl, field);
 		str = Sbar_FixScoreboardColumnWidth(i, str);
 
-		pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+		pos_x += sbar_size[i] + sbar_fontsize_x;
 
 		if(field == SP_NAME) {
-			tmp_x = sbar_fontsize_x*(sbar_size[i] - sbar_fixscoreboardcolumnwidth_iconlen - sbar_fixscoreboardcolumnwidth_marginlen) + sbar_fontsize_x;
+			tmp_x = sbar_size[i] - sbar_fontsize_x*sbar_fixscoreboardcolumnwidth_iconlen - sbar_fixscoreboardcolumnwidth_marginlen + sbar_fontsize_x;
 			if (is_self)
 				drawcolorcodedstring(pos - tmp, str, sbar_fontsize, sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
 			else
 				drawcolorcodedstring(pos - tmp, str, sbar_fontsize, sbar_scoreboard_alpha_name, DRAWFLAG_NORMAL);
 		} else {
-			tmp_x = sbar_fixscoreboardcolumnwidth_len*sbar_fontsize_x + sbar_fontsize_x;
+			tmp_x = sbar_fixscoreboardcolumnwidth_len + sbar_fontsize_x;
 			if (is_self)
 				drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
 			else
 				drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, sbar_scoreboard_alpha_name, DRAWFLAG_NORMAL);
 		}
 
-		tmp_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+		tmp_x = sbar_size[i] + sbar_fontsize_x;
 		if(sbar_field_icon0 != "")
 			if (is_self)
 				drawpic(pos - tmp, sbar_field_icon0, '0 1 0' * sbar_fontsize_y + '1 0 0' * sbar_fontsize_x * sbar_fixscoreboardcolumnwidth_iconlen, sbar_field_icon1_rgb, sbar_field_icon0_alpha * sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
@@ -951,7 +949,7 @@
 				break;
 
 			if(is_spec && field != SP_NAME && field != SP_PING) {
-				pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+				pos_x -= sbar_size[i] + sbar_fontsize_x;
 				continue;
 			}
 
@@ -959,20 +957,20 @@
 			str = Sbar_FixScoreboardColumnWidth(i, str);
 
 			if(field == SP_NAME) {
-				tmp_x = sbar_fontsize_x*sbar_fixscoreboardcolumnwidth_len; // left or right aligned? let's put it right...
+				tmp_x = sbar_fixscoreboardcolumnwidth_len; // left or right aligned? let's put it right...
 				if(is_self)
 					drawcolorcodedstring(pos - tmp, str, sbar_fontsize, sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
 				else
 					drawcolorcodedstring(pos - tmp, str, sbar_fontsize, sbar_scoreboard_alpha_name, DRAWFLAG_NORMAL);
 			} else {
-				tmp_x = sbar_fontsize_x*sbar_fixscoreboardcolumnwidth_len;
+				tmp_x = sbar_fixscoreboardcolumnwidth_len;
 				if(is_self)
 					drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
 				else
 					drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, sbar_scoreboard_alpha_name, DRAWFLAG_NORMAL);
 			}
 
-			tmp_x = sbar_fontsize_x*sbar_size[i];
+			tmp_x = sbar_size[i];
 			if(sbar_field_icon0 != "")
 				if (is_self)
 					drawpic(pos - tmp, sbar_field_icon0, '0 1 0' * sbar_fontsize_y + '1 0 0' * sbar_fontsize_x * sbar_fixscoreboardcolumnwidth_iconlen, sbar_field_icon1_rgb, sbar_field_icon0_alpha * sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
@@ -988,7 +986,7 @@
 					drawpic(pos - tmp, sbar_field_icon2, '0 1 0' * sbar_fontsize_y + '1 0 0' * sbar_fontsize_x * sbar_fixscoreboardcolumnwidth_iconlen, sbar_field_icon2_rgb, sbar_field_icon2_alpha * sbar_scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
 				else
 					drawpic(pos - tmp, sbar_field_icon2, '0 1 0' * sbar_fontsize_y + '1 0 0' * sbar_fontsize_x * sbar_fixscoreboardcolumnwidth_iconlen, sbar_field_icon2_rgb, sbar_field_icon2_alpha * sbar_scoreboard_alpha_name, DRAWFLAG_NORMAL);
-			pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+			pos_x -= sbar_size[i] + sbar_fontsize_x;
 		}
 	}
 }
@@ -1052,7 +1050,7 @@
 	{
 		if(sbar_field[i] == SP_SEPARATOR)
 			break;
-		column_dim_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+		column_dim_x = sbar_size[i] + sbar_fontsize_x;
 		if (sbar_scoreboard_highlight)
 		{
 			if (mod(i,2))
@@ -1070,21 +1068,21 @@
 			if(sbar_field[i] == SP_SEPARATOR)
 				break;
 
-			pos_x -= sbar_size[i]*sbar_fontsize_x;
+			pos_x -= sbar_size[i];
 
 			if (sbar_scoreboard_highlight)
 			{
 				if (!mod(i,2))
 				{
 					if (i == sbar_num_fields-1)
-						column_dim_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x / 2 + 1;
+						column_dim_x = sbar_size[i] + sbar_fontsize_x / 2 + 1;
 					else
-						column_dim_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+						column_dim_x = sbar_size[i] + sbar_fontsize_x;
 					drawfill(pos - '0 1 0' - sbar_fontsize_x / 2 * '1 0 0', column_dim, '0 0 0', sbar_scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
 				}
 			}
 
-			tmp_x = stringwidth(sbar_title[i], FALSE);
+			tmp_x = stringwidth(sbar_title[i], FALSE, sbar_fontsize);
 			tmp_x = (sbar_size[i] - tmp_x) * sbar_fontsize_x;
 			drawstring(pos + tmp, sbar_title[i], sbar_fontsize, rgb * 1.5, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
 			pos_x -= sbar_fontsize_x;
@@ -1216,7 +1214,7 @@
 			s = strcat(ftos(weapon_stats),"%");
 
 			float padding;
-			padding = ((sbwidth/weapon_cnt) - stringwidth(s, FALSE) * fontsize) / 2; // center the accuracy value
+			padding = ((sbwidth/weapon_cnt) - stringwidth(s, FALSE, '1 0 0' * fontsize)) / 2; // center the accuracy value
 
 			rgb = Sbar_AccuracyColor(weapon_stats);
 			drawstring(pos + '1 0 0' * padding + '0 1 0' * height * (2/3), s, '1 1 0' * fontsize, rgb, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
@@ -1376,10 +1374,10 @@
 				continue;
 
 			rgb = GetTeamRGB(tm.team);
-			Sbar_DrawXNum(pos - '6.5 0 0' * sbar_fontsize_y + '0 1 0' * sbar_fontsize_y, tm.(teamscores[ts_primary]), 4, 0, sbar_fontsize_y * 1.5, rgb, 0, 1, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+			Sbar_DrawXNum(pos - '6.5 0 0' * sbar_fontsize_y + '0 1 0' * sbar_fontsize_y, tm.(teamscores[ts_primary]), 6, 0, sbar_fontsize_y * 1.5, rgb, 0, 1, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
 				
 			if(ts_primary != ts_secondary)
-				Sbar_DrawXNum(pos - '4.5 0 0' * sbar_fontsize_y + '0 2.5 0' * sbar_fontsize_y, tm.(teamscores[ts_secondary]), 4, 0, sbar_fontsize_y * 1, rgb, 0, 1, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+				Sbar_DrawXNum(pos - '4.5 0 0' * sbar_fontsize_y + '0 2.5 0' * sbar_fontsize_y, tm.(teamscores[ts_secondary]), 6, 0, sbar_fontsize_y * 1, rgb, 0, 1, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
 
 			pos = Sbar_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
 		}
@@ -1505,7 +1503,7 @@
 
 
 	pos_y += 1.2 * sbar_fontsize_y;
-	drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - sbar_fontsize_x * stringwidth(str, TRUE)), str, sbar_fontsize, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+	drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, TRUE, sbar_fontsize)), str, sbar_fontsize, sbar_scoreboard_alpha_fg, DRAWFLAG_NORMAL);
 
 	scoreboard_bottom = pos_y + 2 * sbar_fontsize_y;
 }
@@ -1600,7 +1598,7 @@
 	a = bound(0, race_status_time - time, 1);
 
 	string s;
-	s = textShortenToWidth(race_status_name, 120/10, stringwidth_colors);
+	s = textShortenToWidth(race_status_name, 120, '10 10 0', stringwidth_colors);
 
 	float rank;
 	if(race_status > 0)
@@ -1612,19 +1610,19 @@
 		drawpic(pos, "gfx/hud/race/newfail", '80 80 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 	else if(race_status == 1) {
 		drawpic(pos, "gfx/hud/race/newtime", '80 80 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);	
-		drawcolorcodedstring(pos + '40 80 0' - '5 0 0' * stringwidth(s, TRUE), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
-		drawstring(pos + '40 20 0' - '7 0 0' * stringwidth(rankname, TRUE), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawcolorcodedstring(pos + '40 80 0' - '1 0 0' * stringwidth(s, TRUE, '5 0 0'), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawstring(pos + '40 20 0' - '1 0 0' * stringwidth(rankname, TRUE, '7 0 0'), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 	} else if(race_status == 2) {
 		if(race_status_name == GetPlayerName(player_localentnum -1) || !race_myrank || race_myrank < rank)
 			drawpic(pos, "gfx/hud/race/newrankgreen", '80 80 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 		else
 			drawpic(pos, "gfx/hud/race/newrankyellow", '80 80 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
-		drawcolorcodedstring(pos + '40 80 0' - '5 0 0' * stringwidth(s, TRUE), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
-		drawstring(pos + '40 20 0' - '7 0 0' * stringwidth(rankname, TRUE), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawcolorcodedstring(pos + '40 80 0' - '1 0 0' * stringwidth(s, TRUE, '5 0 0'), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawstring(pos + '40 20 0' - '1 0 0' * stringwidth(rankname, TRUE, '7 0 0'), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 	} else if(race_status == 3) {
 		drawpic(pos, "gfx/hud/race/newrecordserver", '80 80 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
-		drawcolorcodedstring(pos + '40 80 0' - '5 0 0' * stringwidth(s, TRUE), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
-		drawstring(pos + '40 20 0' - '7 0 0' * stringwidth(rankname, TRUE), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawcolorcodedstring(pos + '40 80 0' - '1 0 0' * stringwidth(s, TRUE, '5 0 0'), s, '10 10 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+		drawstring(pos + '40 20 0' - '1 0 0' * stringwidth(rankname, TRUE, '7 0 0'), rankname, '14 14 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 	}
 
 	if (race_status_time - time <= 0) {
@@ -1651,8 +1649,8 @@
  	bottomright_y = vid_conheight;
  	bottomright_z = 0;
 
-	score_pos = bottomright - '196 42 0';
-	secondary_score_pos = score_pos + '132 -6 0';
+	score_pos = bottomright - '245 42 0'; // for same alignment as before: 294
+	secondary_score_pos = score_pos + '149 -6 0';
 
 	if((scores_flags[ps_primary] & SFL_TIME) && !teamplay) { // race/cts record display on HUD
 		pl = players.sort_next;
@@ -1731,8 +1729,8 @@
 		else
 			distribution_color = '1 0 0';
 		
-		Sbar_DrawXNum(secondary_score_pos, distribution, 4, 3, 16, distribution_color, 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL);
-		Sbar_DrawXNum(score_pos, score, 4, 0, 34, distribution_color, leader, 0, sbar_alpha_fg, DRAWFLAG_NORMAL);
+		Sbar_DrawXNum(secondary_score_pos, distribution, 6, 3, 16, distribution_color, 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL);
+		Sbar_DrawXNum(score_pos, score, 6, 0, 34, distribution_color, leader, 0, sbar_alpha_fg, DRAWFLAG_NORMAL);
 	} else { // teamgames
 		float max_fragcount;
 		max_fragcount = -999;
@@ -1753,7 +1751,7 @@
 			} else {
 				if (max_fragcount == score)
 					leader = 1;
-				Sbar_DrawXNum(secondary_score_pos, score, 4, 0, 16, GetTeamRGB(tm.team) * 0.8, leader, 1, sbar_alpha_fg, DRAWFLAG_NORMAL);
+				Sbar_DrawXNum(secondary_score_pos, score, 6, 0, 16, GetTeamRGB(tm.team) * 0.8, leader, 1, sbar_alpha_fg, DRAWFLAG_NORMAL);
 				secondary_score_pos = secondary_score_pos + '0 16 0';
 			}
 		}
@@ -1800,7 +1798,8 @@
 			if(s != "" && a > 0)
 			{
 				dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-				drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				//drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				drawcolorcodedstring(m - '0 16 0' - '0.5 0 0' * stringwidth(s, TRUE, '16 16 0'), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 
 			if(race_penaltytime)
@@ -1810,14 +1809,16 @@
 				{
 					s = strcat("^1PENALTY: ", ftos_decimals(race_penaltytime * 0.1, 1), " (", race_penaltyreason, ")");
 					dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-					drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+					//drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+					drawcolorcodedstring(m - '0 32 0' - '0.5 0 0' * stringwidth(s, TRUE, '16 16 0'), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 				}
 			}
 
 			if(forcetime != "")
 			{
 				a = bound(0, (time - race_checkpointtime) / 0.5, 1);
-				drawstring_expanding(m - '16 0 0' * stringwidth(forcetime, FALSE), forcetime, '32 32 0', '1 1 1', sbar_alpha_fg, 0, a);
+				//drawstring_expanding(m - '16 0 0' * stringwidth(forcetime, FALSE), forcetime, '32 32 0', '1 1 1', sbar_alpha_fg, 0, a);
+				drawstring_expanding(m - '1 0 0' * stringwidth(forcetime, FALSE, '16 0 0'), forcetime, '32 32 0', '1 1 1', sbar_alpha_fg, 0, a);
 			}
 			else
 				a = 1;
@@ -1825,7 +1826,8 @@
 			if(race_laptime && race_checkpoint != 255)
 			{
 				s = TIME_ENCODED_TOSTRING(TIME_ENCODE(time + TIME_DECODE(race_penaltyaccumulator) - race_laptime));
-				drawstring(m - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				//drawstring(m - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				drawstring(m - '0.5 0 0' * stringwidth(s, FALSE, '32 32 0'), s, '32 32 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 		}
 		else
@@ -1835,14 +1837,16 @@
 				a = bound(0, 2 - (time - race_mycheckpointtime), 1);
 				s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -!race_mycheckpointenemy, race_mycheckpointlapsdelta, race_mycheckpointenemy);
 				dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-				drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				//drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				drawcolorcodedstring(m - '0 16 0' - '0.5 0 0' * stringwidth(s, TRUE, '16 16 0'), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 			if(race_othercheckpointtime && race_othercheckpointenemy != "")
 			{
 				a = bound(0, 2 - (time - race_othercheckpointtime), 1);
 				s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -!race_othercheckpointenemy, race_othercheckpointlapsdelta, race_othercheckpointenemy);
 				dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-				drawcolorcodedstring(m - '0 0 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				//drawcolorcodedstring(m - '0 0 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				drawcolorcodedstring(m - '0 0 0' - '0.5 0 0' * stringwidth(s, TRUE, '16 16 0'), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 
 			if(race_penaltytime && !race_penaltyaccumulator)
@@ -1856,7 +1860,8 @@
 					else
 						s = strcat("^2PENALTY: 0.0 (", race_penaltyreason, ")");
 					dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-					drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+					//drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+					drawcolorcodedstring(m - '0 32 0' - '0.5 0 0' * stringwidth(s, TRUE, '16 16 0'), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 				}
 			}
 		}
@@ -2077,11 +2082,11 @@
 		getWrappedLine_remaining = argv(j);
 		while(getWrappedLine_remaining)
 		{
-			s = getWrappedLine(vid_conwidth * 0.75 / centerprint_fontsize_x, stringwidth_colors);
+			s = getWrappedLine(vid_conwidth * 0.75, centerprint_fontsize, stringwidth_colors);
 			if(centerprint_messages[i])
 				strunzone(centerprint_messages[i]);
 			centerprint_messages[i] = strzone(s);
-			centerprint_width[i] = stringwidth(s, TRUE);
+			centerprint_width[i] = stringwidth(s, TRUE, centerprint_fontsize);
 			++i;
 
 			// half height for empty lines looks better
@@ -2190,7 +2195,7 @@
 	pos = centerprint_start;
 	for (i=0; i<centerprint_num; i = i + 1)
 	{
-		pos_x = (vid_conwidth - centerprint_fontsize_x * centerprint_width[i]) * 0.5;
+		pos_x = (vid_conwidth - centerprint_width[i]) * 0.5;
 		ts = centerprint_messages[i];
 		if (ts != "")
 		{
@@ -2209,7 +2214,7 @@
 {
 	dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
 	drawcolorcodedstring(
-		offset - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+		offset - '1 0 0' * stringwidth(s, TRUE, sbar_fontsize),
 		s,
 		sbar_fontsize,
 		sbar_alpha_fg,
@@ -2647,7 +2652,7 @@
 		// spectated player name between HUD and chat area, aligned to the left
 		pos_x = bottomleft_x;
 		pos_y = bottom_y - 50 - sbar_fontsize_spec_y;
-		s = textShortenToWidth(s, vid_conwidth/2.5/sbar_fontsize_spec_x, stringwidth_colors);
+		s = textShortenToWidth(s, vid_conwidth/2.5, sbar_fontsize_spec, stringwidth_colors);
 		drawcolorcodedstring(pos, s, sbar_fontsize_spec, sbar_alpha_fg, DRAWFLAG_NORMAL);
 		drawfont = sbar_font;
 
@@ -2790,15 +2795,15 @@
 
 		string s;
 	        s = "A vote has been called for: ";
-		drawstring(origin + '0.5 0 0' * size_x + '0 0.1 0' * size_y - '6 0 0' * stringwidth(s, FALSE), s, '12 12 0', '1 1 1', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
-		s = textShortenToWidth(vote_called_vote, size_x * 0.96/10, stringwidth_colors);
-		drawcolorcodedstring(origin + '0.52 0 0' * size_x + '0 0.3 0' * size_y - '5 0 0' * stringwidth(s, FALSE), s, '10 10 0', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
+		drawstring(origin + '0.5 0 0' * size_x + '0 0.1 0' * size_y - '1 0 0' * stringwidth(s, FALSE, '6 0 0'), s, '12 12 0', '1 1 1', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
+		s = textShortenToWidth(vote_called_vote, size_x * 0.96, '10 0 0', stringwidth_colors);
+		drawcolorcodedstring(origin + '0.52 0 0' * size_x + '0 0.3 0' * size_y - '1 0 0' * stringwidth(s, FALSE, '5 0 0'), s, '10 10 0', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
 
 		// print the yes/no counts
 		s = strcat("Yes: ", ftos(vote_yescount));
 		drawstring(origin + '0 0.6 0' * size_y + '0.02 0 0' * size_x, s, '12 12 0', '0 1 0', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
 		s = strcat("No: ", ftos(vote_nocount));
-		drawstring(origin + '0 0.6 0' * size_y + '0.98 0 0' * size_x - '12 0 0' * stringwidth(s, FALSE), s, '12 12 0', '1 0 0', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
+		drawstring(origin + '0 0.6 0' * size_y + '0.98 0 0' * size_x - '1 0 0' * stringwidth(s, FALSE, '12 0 0'), s, '12 12 0', '1 0 0', a * sbar_alpha_fg, DRAWFLAG_NORMAL);
 
 		// draw the progress bars
 		drawsetcliparea(origin_x, origin_y, size_x * 0.5 * (vote_yescount/vote_needed), size_y);

Modified: trunk/data/qcsrc/common/gamecommand.qc
===================================================================
--- trunk/data/qcsrc/common/gamecommand.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/common/gamecommand.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -178,6 +178,8 @@
 		print("    f1 f2 b when ----------------------> f   : f1 if b, f2 otherwise\n");
 		print("    s s union|intersection|difference -> s   : set operations\n");
 		print("    s shuffle -------------------------> s   : randomly arrange elements\n");
+		print("    /key /value put ------------------->     : set a database key\n");
+		print("    /key get --------------------------> s   : get a database value\n");
 		print("    x dbpush -------------------------->     : pushes the top onto the database\n");
 		print("    dbpop|dbget -----------------------> x   : removes/reads DB's top\n");
 		print("    dblen|dbat ------------------------> f   : gets the DB's size/cursor pos\n");
@@ -506,6 +508,18 @@
 					rpn_setf(ceil(random() * rpn_getf()) - 1);
 				} else if(rpncmd == "crc16") {
 					rpn_setf(crc16(FALSE, rpn_get()));
+				} else if(rpncmd == "put") {
+					s2 = rpn_pop();
+					if (!rpn_error)
+					{
+						s = rpn_pop();
+						if (!rpn_error)
+							db_put(rpn_db, s, s2);
+					}
+				} else if(rpncmd == "get") {
+					s = rpn_pop();
+					if (!rpn_error)
+						rpn_push(db_get(rpn_db, s));
 				} else if(rpncmd == "dbpush") {
 					s = rpn_pop();
 					if(!rpn_error)

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/common/util.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -1260,11 +1260,80 @@
 }
 #endif
 
-float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t w)
+float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
 {
 	float ICanHasKallerz;
 
 	// detect color codes support in the width function
+	ICanHasKallerz = (w("^7", theSize) == 0);
+
+	// STOP.
+	// The following function is SLOW.
+	// For your safety and for the protection of those around you...
+	// DO NOT CALL THIS AT HOME.
+	// No really, don't.
+	if(w(theText, theSize) <= maxWidth)
+		return strlen(theText); // yeah!
+
+	// binary search for right place to cut string
+	float ch;
+	float left, right, middle; // this always works
+	left = 0;
+	right = strlen(theText); // this always fails
+	do
+	{
+		middle = floor((left + right) / 2);
+		if(w(substring(theText, 0, middle), theSize) <= maxWidth)
+			left = middle;
+		else
+			right = middle;
+	}
+	while(left < right - 1);
+
+	if(ICanHasKallerz)
+	{
+		// NOTE: when color codes are involved, this binary search is,
+		// mathematically, BROKEN. However, it is obviously guaranteed to
+		// terminate, as the range still halves each time - but nevertheless, it is
+		// guaranteed that it finds ONE valid cutoff place (where "left" is in
+		// range, and "right" is outside).
+		
+		// terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4)
+		// and decrease left on the basis of the chars detected of the truncated tag
+		// Even if the ^xrgb tag is not complete/correct, left is decreased
+		// (sometimes too much but with a correct result)
+		// it fixes also ^[0-9]
+		while(left >= 1 && substring(theText, left-1, 1) == "^")
+			left-=1;
+
+		if (left >= 2 && substring(theText, left-2, 2) == "^x") // ^x/
+			left-=2;
+		else if (left >= 3 && substring(theText, left-3, 2) == "^x")
+			{
+				ch = str2chr(theText, left-1);
+				if( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xr/
+					left-=3;
+			}
+		else if (left >= 4 && substring(theText, left-4, 2) == "^x")
+			{
+				ch = str2chr(theText, left-2);
+				if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') )
+				{
+					ch = str2chr(theText, left-1);
+					if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xrg/
+						left-=4;
+				}
+			}
+	}
+	
+	return left;
+}
+
+float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t w)
+{
+	float ICanHasKallerz;
+
+	// detect color codes support in the width function
 	ICanHasKallerz = (w("^7") == 0);
 
 	// STOP.
@@ -1329,7 +1398,7 @@
 	return left;
 }
 
-string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw)
+string getWrappedLine(float w, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
 {
 	float cantake;
 	float take;
@@ -1337,7 +1406,7 @@
 
 	s = getWrappedLine_remaining;
 
-	cantake = textLengthUpToWidth(s, w, tw);
+	cantake = textLengthUpToWidth(s, w, theFontSize, tw);
 	if(cantake > 0 && cantake < strlen(s))
 	{
 		take = cantake - 1;
@@ -1365,12 +1434,56 @@
 	}
 }
 
-string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw)
+string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw)
 {
+	float cantake;
+	float take;
+	string s;
+
+	s = getWrappedLine_remaining;
+
+	cantake = textLengthUpToLength(s, w, tw);
+	if(cantake > 0 && cantake < strlen(s))
+	{
+		take = cantake - 1;
+		while(take > 0 && substring(s, take, 1) != " ")
+			--take;
+		if(take == 0)
+		{
+			getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
+			if(getWrappedLine_remaining == "")
+				getWrappedLine_remaining = string_null;
+			return substring(s, 0, cantake);
+		}
+		else
+		{
+			getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
+			if(getWrappedLine_remaining == "")
+				getWrappedLine_remaining = string_null;
+			return substring(s, 0, take);
+		}
+	}
+	else
+	{
+		getWrappedLine_remaining = string_null;
+		return s;
+	}
+}
+
+string textShortenToWidth(string theText, float maxWidth, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
+{
+	if(tw(theText, theFontSize) <= maxWidth)
+		return theText;
+	else
+		return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - tw("...", theFontSize), theFontSize, tw)), "...");
+}
+
+string textShortenToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t tw)
+{
 	if(tw(theText) <= maxWidth)
 		return theText;
 	else
-		return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - tw("..."), tw)), "...");
+		return strcat(substring(theText, 0, textLengthUpToLength(theText, maxWidth - tw("..."), tw)), "...");
 }
 
 float isGametypeInFilter(float gt, float tp, string pattern)

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/common/util.qh	2010-01-24 21:44:44 UTC (rev 8546)
@@ -140,12 +140,16 @@
 vector AnglesTransform_Divide(vector to_transform, vector from_transform);
 #endif
 
-typedef float(string s) textLengthUpToWidth_widthFunction_t;
-float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw);
-string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw);
+typedef float(string s, vector size) textLengthUpToWidth_widthFunction_t;
+typedef float(string s) textLengthUpToLength_lenFunction_t;
+float textLengthUpToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
+string textShortenToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
+float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t tw);
+string textShortenToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t tw);
 
 string getWrappedLine_remaining;
-string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw);
+string getWrappedLine(float w, vector size, textLengthUpToWidth_widthFunction_t tw);
+string getWrappedLineLen(float w, textLengthUpToLength_lenFunction_t tw);
 
 float isGametypeInFilter(float gt, float tp, string pattern);
 

Modified: trunk/data/qcsrc/menu/draw.qc
===================================================================
--- trunk/data/qcsrc/menu/draw.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/draw.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -249,26 +249,30 @@
 }
 void draw_CenterText(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
 {
-	draw_Text(theOrigin - eX * theSize_x * 0.5 * draw_TextWidth(theText, ICanHasKallerz), theText, theSize, theColor, theAlpha, ICanHasKallerz);
+	//print(strcat("orig = ", vtos(theOrigin) ," tx = ", ftos(draw_TextWidth(theText, ICanHasKallerz, theSize)), "\n"));
+	draw_Text(theOrigin - eX * 0.5 * draw_TextWidth(theText, ICanHasKallerz, theSize), theText, theSize, theColor, theAlpha, ICanHasKallerz);
 }
 
-float draw_TextWidth(string theText, float ICanHasKallerz)
+float draw_TextWidth(string theText, float ICanHasKallerz, vector SizeThxBye)
 {
 	//return strlen(theText);
 	//print("draw_TextWidth \"", theText, "\"\n");
 	vector fs;
-	float r;
+	vector v;
+	v = '0 0 0';
+	//float r;
 	if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines
 	{
 		fs = draw_fontscale;
 		draw_fontscale = '1 1 0';
 	}
-	r = stringwidth(theText, ICanHasKallerz) / draw_fontscale_x;
+	v_x = stringwidth(theText, ICanHasKallerz, boxToGlobalSize(SizeThxBye, draw_scale)) / draw_fontscale_x;
 	if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines
 	{
 		draw_fontscale = fs;
 	}
-	return r;
+	v = globalToBoxSize(v, draw_scale);
+	return v_x;
 }
 
 float draw_clipSet;
@@ -299,28 +303,34 @@
 	draw_clipSet = 0;
 }
 
-string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz)
+string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz, vector SizeThxBye)
 {
+	/*
+	if(draw_TextWidth(theText, ICanHasKallerz, SizeThxBye) <= maxWidth)
+		return theText;
+	else
+		return strcat(substring(theText, 0, draw_TextLengthUpToWidth(theText, maxWidth - draw_TextWidth("...", ICanHasKallerz, SizeThxBye), ICanHasKallerz, SizeThxBye)), "...");
+	*/
 	if(ICanHasKallerz)
-		return textShortenToWidth(theText, maxWidth, draw_TextWidth_WithColors);
+		return textShortenToWidth(theText, maxWidth, SizeThxBye, draw_TextWidth_WithColors);
 	else
-		return textShortenToWidth(theText, maxWidth, draw_TextWidth_WithoutColors);
+		return textShortenToWidth(theText, maxWidth, SizeThxBye, draw_TextWidth_WithoutColors);
 }
 
-float draw_TextWidth_WithColors(string s)
+float draw_TextWidth_WithColors(string s, vector theFontSize)
 {
-	return draw_TextWidth(s, TRUE);
+	return draw_TextWidth(s, TRUE, theFontSize);
 }
 
-float draw_TextWidth_WithoutColors(string s)
+float draw_TextWidth_WithoutColors(string s, vector theFontSize)
 {
-	return draw_TextWidth(s, FALSE);
+	return draw_TextWidth(s, FALSE, theFontSize);
 }
 
-float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes)
+float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes, vector theFontSize)
 {
 	if(allowColorCodes)
-		return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithColors);
+		return textLengthUpToWidth(theText, maxWidth, theFontSize, draw_TextWidth_WithColors);
 	else
-		return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithoutColors);
+		return textLengthUpToWidth(theText, maxWidth, theFontSize, draw_TextWidth_WithoutColors);
 }

Modified: trunk/data/qcsrc/menu/draw.qh
===================================================================
--- trunk/data/qcsrc/menu/draw.qh	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/draw.qh	2010-01-24 21:44:44 UTC (rev 8546)
@@ -23,9 +23,9 @@
 void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha);
 void draw_Text(vector origin, string text, vector size, vector color, float alpha, float allowColorCodes);
 void draw_CenterText(vector origin, string text, vector size, vector color, float alpha, float allowColorCodes);
-float draw_TextWidth(string text, float allowColorCodes);
-string draw_TextShortenToWidth(string text, float maxWidth, float allowColorCodes);
-float draw_TextLengthUpToWidth(string text, float maxWidth, float allowColorCodes);
+float draw_TextWidth(string text, float allowColorCodes, vector size);
+string draw_TextShortenToWidth(string text, float maxWidth, float allowColorCodes, vector size);
+float draw_TextLengthUpToWidth(string text, float maxWidth, float allowColorCodes, vector size);
 
 void draw_SetClip();
 void draw_SetClipRect(vector theOrigin, vector theScale);
@@ -40,5 +40,5 @@
 
 string draw_currentSkin;
 
-float draw_TextWidth_WithColors(string s);
-float draw_TextWidth_WithoutColors(string s);
+float draw_TextWidth_WithColors(string s, vector size);
+float draw_TextWidth_WithoutColors(string s, vector size);

Modified: trunk/data/qcsrc/menu/item/inputbox.c
===================================================================
--- trunk/data/qcsrc/menu/item/inputbox.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/item/inputbox.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -55,7 +55,7 @@
 	float p;
 	me.dragScrollPos = pos;
 	p = me.scrollPos + pos_x - me.keepspaceLeft;
-	me.cursorPos = draw_TextLengthUpToWidth(me.text, p / me.realFontSize_x, 0);
+	me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
 	me.lastChangeTime = time;
 	return 1;
 }
@@ -146,8 +146,8 @@
 	}
 
 	me.cursorPos = bound(0, me.cursorPos, strlen(me.text));
-	cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0) * me.realFontSize_x;
-	totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0) * me.realFontSize_x;
+	cursorPosInWidths = draw_TextWidth(substring(me.text, 0, me.cursorPos), 0, me.realFontSize);
+	totalSizeInWidths = draw_TextWidth(strcat(me.text, CURSOR), 0, me.realFontSize);
 
 	if(me.dragScrollTimer < time)
 	{
@@ -183,7 +183,7 @@
 			{
 				float w;
 				ch2 = substring(me.text, i+1, 1);
-				w = draw_TextWidth(strcat(ch, ch2), 0) * me.realFontSize_x;
+				w = draw_TextWidth(strcat(ch, ch2), 0, me.realFontSize);
 				if(ch2 == "^")
 				{
 					draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
@@ -227,7 +227,7 @@
 							{
 								theTempColor_z = component/15;
 								theColor = theTempColor;
-								w = draw_TextWidth(substring(me.text, i, 5), 0) * me.realFontSize_x;
+								w = draw_TextWidth(substring(me.text, i, 5), 0, me.realFontSize);
 								
 								draw_Fill(p, eX * w + eY * me.realFontSize_y, '1 1 1', 0.5);
 								draw_Text(p, substring(me.text, i, 5), me.realFontSize, theColor, 1, 0);    // theVariableAlpha instead of 1 using alpha tags ^ax
@@ -236,7 +236,7 @@
 							else
 							{
 								// blue missing
-								w = draw_TextWidth(substring(me.text, i, 4), 0) * me.realFontSize_x;
+								w = draw_TextWidth(substring(me.text, i, 4), 0, me.realFontSize);
 								draw_Fill(p, eX * w + eY * me.realFontSize_y, eZ, 0.5);
 								draw_Text(p, substring(me.text, i, 4), me.realFontSize, '1 1 1', theAlpha, 0);
 								i += 2;
@@ -245,7 +245,7 @@
 						else
 						{
 							// green missing
-							w = draw_TextWidth(substring(me.text, i, 3), 0) * me.realFontSize_x;
+							w = draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize);
 							draw_Fill(p, eX * w + eY * me.realFontSize_y, eY, 0.5);
 							draw_Text(p, substring(me.text, i, 3), me.realFontSize, '1 1 1', theAlpha, 0);
 							i += 1;
@@ -284,7 +284,7 @@
 						else
 							theVariableAlpha = component*0.0625;
 						
-						draw_Fill(p, eX * draw_TextWidth(substring(me.text, i, 3), 0) * me.realFontSize_x + eY * me.realFontSize_y, '0.8 0.8 0.8', 0.5);
+						draw_Fill(p, eX * draw_TextWidth(substring(me.text, i, 3), 0, me.realFontSize) + eY * me.realFontSize_y, '0.8 0.8 0.8', 0.5);
 						draw_Text(p, strcat(ch, ch2), me.realFontSize, theColor, 0.8, 0);
 					}
 				}*/
@@ -298,7 +298,7 @@
 				continue;
 			}
 			draw_Text(p, ch, me.realFontSize, theColor, theAlpha, 0); // TODO theVariableAlpha
-			p += eX * draw_TextWidth(ch, 0) * me.realFontSize_x;
+			p += eX * draw_TextWidth(ch, 0, me.realFontSize);
 		}
 	}
 	else

Modified: trunk/data/qcsrc/menu/item/label.c
===================================================================
--- trunk/data/qcsrc/menu/item/label.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/item/label.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -33,7 +33,7 @@
 void setTextLabel(entity me, string txt)
 {
 	me.text = txt;
-	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(me.realFontSize_x * draw_TextWidth(me.text, me.allowColors), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(me.text, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
 }
 void resizeNotifyLabel(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
@@ -45,7 +45,7 @@
 		me.keepspaceLeft = me.marginLeft * me.realFontSize_x;
 	if(me.marginRight)
 		me.keepspaceRight = me.marginRight * me.realFontSize_x;
-	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(me.realFontSize_x * draw_TextWidth(me.text, me.allowColors), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+	me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(me.text, me.allowColors, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
 	me.realOrigin_y = 0.5 * (1 - me.realFontSize_y);
 }
 void configureLabelLabel(entity me, string txt, float sz, float algn)
@@ -64,7 +64,7 @@
 	if(me.textEntity)
 	{
 		t = me.textEntity.toString(me.textEntity);
-		me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(me.realFontSize_x * draw_TextWidth(t, 0), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
+		me.realOrigin_x = me.align * (1 - me.keepspaceLeft - me.keepspaceRight - min(draw_TextWidth(t, 0, me.realFontSize), (1 - me.keepspaceLeft - me.keepspaceRight))) + me.keepspaceLeft;
 	}
 	else
 		t = me.text;
@@ -73,7 +73,7 @@
 		if(t)
 		{
 			if(me.allowCut) // FIXME allowCut incompatible with align != 0
-				draw_Text(me.realOrigin, draw_TextShortenToWidth(t, (1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x, me.allowColors), me.realFontSize, me.colorL, me.alpha, me.allowColors);
+				draw_Text(me.realOrigin, draw_TextShortenToWidth(t, (1 - me.keepspaceLeft - me.keepspaceRight), me.allowColors, me.realFontSize), me.realFontSize, me.colorL, me.alpha, me.allowColors);
 			else if(me.allowWrap) // FIXME allowWrap incompatible with align != 0
 			{
 				getWrappedLine_remaining = t;
@@ -81,9 +81,9 @@
 				while(getWrappedLine_remaining)
 				{
 					if (me.allowColors)
-						t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x, draw_TextWidth_WithColors);
+						t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), me.realFontSize, draw_TextWidth_WithColors);
 					else
-						t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x, draw_TextWidth_WithoutColors);
+						t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight), me.realFontSize, draw_TextWidth_WithoutColors);
 					draw_Text(o, t, me.realFontSize, me.colorL, me.alpha, me.allowColors);
 					o_y += me.realFontSize_y;
 				}

Modified: trunk/data/qcsrc/menu/mbuiltin.qh
===================================================================
--- trunk/data/qcsrc/menu/mbuiltin.qh	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/mbuiltin.qh	2010-01-24 21:44:44 UTC (rev 8546)
@@ -195,7 +195,7 @@
 
 float	drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
 float   drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #467;
-float	stringwidth(string text, float handleColors) = #468;
+float	stringwidth(string text, float handleColors, vector size) = #468;
 
 float	drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456;
 float	drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) = #469;

Modified: trunk/data/qcsrc/menu/menu.qc
===================================================================
--- trunk/data/qcsrc/menu/menu.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/menu.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -462,13 +462,13 @@
 					getWrappedLine_remaining = it.tooltip;
 					while(getWrappedLine_remaining)
 					{
-						s = getWrappedLine(SKINWIDTH_TOOLTIP / fontsize_x, draw_TextWidth_WithoutColors);
+						s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
 						++i;
-						f = draw_TextWidth(s, FALSE);
+						f = draw_TextWidth(s, FALSE, fontsize);
 						if(f > w)
 							w = f;
 					}
-					menuTooltipSize_x = w * fontsize_x + 2 * (SKINMARGIN_TOOLTIP_x / conwidth);
+					menuTooltipSize_x = w + 2 * (SKINMARGIN_TOOLTIP_x / conwidth);
 					menuTooltipSize_y = i * fontsize_y + 2 * (SKINMARGIN_TOOLTIP_y / conheight);
 					menuTooltipSize_z = 0;
 				}
@@ -524,7 +524,7 @@
 			getWrappedLine_remaining = menuTooltipItem.tooltip;
 			while(getWrappedLine_remaining)
 			{
-				s = getWrappedLine(SKINWIDTH_TOOLTIP / fontsize_x, draw_TextWidth_WithoutColors);
+				s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
 				draw_Text(p, s, fontsize, '1 1 1', SKINALPHA_TOOLTIP * menuTooltipAlpha, FALSE);
 				p_y += fontsize_y;
 			}

Modified: trunk/data/qcsrc/menu/nexuiz/campaign.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/campaign.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/campaign.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -49,7 +49,7 @@
 #ifdef IMPLEMENTATION
 string campaign_longdesc_wrapped[CAMPAIGN_MAX_ENTRIES];
 
-void rewrapCampaign(float w, float l0, float emptyheight)
+void rewrapCampaign(float w, float l0, float emptyheight, vector theFontSize)
 {
 	float i, j;
 	float n, l;
@@ -74,7 +74,7 @@
 			getWrappedLine_remaining = s;
 			while(getWrappedLine_remaining)
 			{
-				s = getWrappedLine(w, draw_TextWidth_WithoutColors);
+				s = getWrappedLine(w, theFontSize, draw_TextWidth_WithoutColors);
 				if(--l < 0) goto toolong;
 				r = strcat(r, s, "\n");
 			}
@@ -125,7 +125,7 @@
 	me.campaignIndex = bound(0, cvar(me.cvarName), campaign_entries);
 	cvar_set(me.cvarName, ftos(me.campaignIndex));
 	if(me.columnNameSize)
-		rewrapCampaign(me.columnNameSize / me.realFontSize_x, me.rowsPerItem - 3, me.emptyLineHeight);
+		rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize);
 	me.nItems = min(me.campaignIndex + 2, campaign_entries);
 	me.selectedItem = min(me.campaignIndex, me.nItems - 1);
 	me.scrollPos = me.nItems * me.itemHeight - 1;
@@ -231,7 +231,7 @@
 
 	me.checkMarkOrigin = eY + eX * (me.columnCheckMarkOrigin + me.columnCheckMarkSize) - me.checkMarkSize;
 
-	rewrapCampaign(me.columnNameSize / me.realFontSize_x, me.rowsPerItem - 3, me.emptyLineHeight);
+	rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize);
 }
 void clickListBoxItemNexuizCampaignList(entity me, float i, vector where)
 {
@@ -282,8 +282,8 @@
 		s = campaign_shortdesc[i]; // fteqcc sucks
 	else
 		s = "???";
-	s = draw_TextShortenToWidth(strcat("Level ", ftos(i + 1), ": ", s), me.columnNameSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
+	s = draw_TextShortenToWidth(strcat("Level ", ftos(i + 1), ": ", s), me.columnNameSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 
 	if(i <= me.campaignIndex)
 	{

Modified: trunk/data/qcsrc/menu/nexuiz/charmap.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/charmap.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/charmap.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -30,12 +30,21 @@
 
 string CharMap_CellToChar(float c)
 {
-	if(c == 13)
-		return chr(127);
-	else if(c < 32)
-		return chr(c);
-	else
-		return chr(c + 96);
+	if (cvar("utf8_enable")) {
+		if(c == 13)
+			return chr(0xE000 + 127);
+		else if(c < 32)
+			return chr(0xE000 + c);
+		else
+			return chr(0xE000 + c + 96);
+	} else {
+		if(c == 13)
+			return chr(127);
+		else if(c < 32)
+			return chr(c);
+		else
+			return chr(c + 96);
+	}
 }
 
 void configureNexuizCharmapNexuizCharmap(entity me, entity theTextbox)

Modified: trunk/data/qcsrc/menu/nexuiz/cvarlist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/cvarlist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/cvarlist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -149,9 +149,9 @@
 	else
 		theColor = SKINCOLOR_CVARLIST_CHANGED;
 
-	s = draw_TextShortenToWidth(k, me.columnNameSize / me.realFontSize_x, 0);
+	s = draw_TextShortenToWidth(k, me.columnNameSize, 0, me.realFontSize);
 	draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0);
-	s = draw_TextShortenToWidth(v, me.columnValueSize / me.realFontSize_x, 0);
+	s = draw_TextShortenToWidth(v, me.columnValueSize, 0, me.realFontSize);
 	draw_Text(me.realUpperMargin * eY + me.columnValueOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0);
 }
 

Modified: trunk/data/qcsrc/menu/nexuiz/demolist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/demolist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/demolist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -99,8 +99,8 @@
     	draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
 		
     s = me.demoName(me,i);
-    s = draw_TextShortenToWidth(s, me.columnNameSize / me.realFontSize_x, 0);
-    draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);		
+    s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
+    draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);		
 }
 
 void showNotifyNexuizDemoList(entity me)

Modified: trunk/data/qcsrc/menu/nexuiz/keybinder.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/keybinder.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/keybinder.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -312,7 +312,7 @@
 				s = strcat(s, keynumtostring(k));
 			}
 		}
-		s = draw_TextShortenToWidth(s, me.columnKeysSize / me.realFontSize_x, 0);
+		s = draw_TextShortenToWidth(s, me.columnKeysSize, 0, me.realFontSize);
 		draw_CenterText(me.realUpperMargin * eY + (me.columnKeysOrigin + 0.5 * me.columnKeysSize) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 	}
 }

Modified: trunk/data/qcsrc/menu/nexuiz/maplist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/maplist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/maplist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -189,10 +189,10 @@
 	draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
 	if(included)
 		draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1);
-	s = draw_TextShortenToWidth(strcat(MapInfo_Map_bspname, ": ", MapInfo_Map_title), me.columnNameSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_TITLE, theAlpha, 0);
-	s = draw_TextShortenToWidth(MapInfo_Map_author, me.columnNameSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_AUTHOR, theAlpha, 0);
+	s = draw_TextShortenToWidth(strcat(MapInfo_Map_bspname, ": ", MapInfo_Map_title), me.columnNameSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_TITLE, theAlpha, 0);
+	s = draw_TextShortenToWidth(MapInfo_Map_author, me.columnNameSize, 0,  me.realFontSize);
+	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_AUTHOR, theAlpha, 0);
 
 	MapInfo_ClearTemps();
 }

Modified: trunk/data/qcsrc/menu/nexuiz/playerlist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/playerlist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/playerlist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -127,11 +127,11 @@
 			score = substring(score, 0, t);
 	}
 
-	s = draw_TextShortenToWidth(s, (me.columnNameSize / me.realFontSize_x), 1);
-	score = draw_TextShortenToWidth(score, me.columnScoreSize / me.realFontSize_x, 0);
+	s = draw_TextShortenToWidth(s, me.columnNameSize, 1, me.realFontSize);
+	score = draw_TextShortenToWidth(score, me.columnScoreSize, 0, me.realFontSize);
 
-	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 1) * me.realFontSize_x)) * eX, s, me.realFontSize, '1 1 1', 1, 1);
-	draw_Text(me.realUpperMargin2 * eY + (me.columnScoreOrigin + 1.00 * (me.columnScoreSize - draw_TextWidth(score, 1) * me.realFontSize_x)) * eX, score, me.realFontSize, rgb, 1, 0);
+	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 1, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', 1, 1);
+	draw_Text(me.realUpperMargin2 * eY + (me.columnScoreOrigin + 1.00 * (me.columnScoreSize - draw_TextWidth(score, 1, me.realFontSize))) * eX, score, me.realFontSize, rgb, 1, 0);
 }
 
 #endif

Modified: trunk/data/qcsrc/menu/nexuiz/serverlist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/serverlist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/serverlist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -557,21 +557,21 @@
 	}
 
 	s = ftos(p);
-	draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0) * me.realFontSize_x) * eX, s, me.realFontSize, theColor, theAlpha, 0);
-	s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize / me.realFontSize_x, 0);
+	draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
+	s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize);
 	draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0);
-	s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
+	s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 	s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
 	p = strstrofs(s, ":", 0);
 	if(p >= 0)
 		s = substring(s, 0, p);
 	else
 		s = "";
-	s = draw_TextShortenToWidth(s, me.columnMapSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
+	s = draw_TextShortenToWidth(s, me.columnMapSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 	s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i)));
-	draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
+	draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 }
 
 float keyDownNexuizServerList(entity me, float scan, float ascii, float shift)

Modified: trunk/data/qcsrc/menu/nexuiz/skinlist.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/skinlist.c	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/skinlist.c	2010-01-24 21:44:44 UTC (rev 8546)
@@ -161,12 +161,12 @@
 	
 	s = me.skinParameter(me, i, SKINPARM_NAME);
 	s = strcat(s, ": ", me.skinParameter(me, i, SKINPARM_TITLE));
-	s = draw_TextShortenToWidth(s, me.columnNameSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0);
+	s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0);
 
 	s = me.skinParameter(me, i, SKINPARM_AUTHOR);
-	s = draw_TextShortenToWidth(s, me.columnNameSize / me.realFontSize_x, 0);
-	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_AUTHOR, SKINALPHA_TEXT, 0);
+	s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
+	draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_AUTHOR, SKINALPHA_TEXT, 0);
 }
 
 void setSkinNexuizSkinList(entity me)

Modified: trunk/data/qcsrc/menu/nexuiz/util.qc
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/util.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/menu/nexuiz/util.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -341,7 +341,7 @@
 	{
 		fs = ((1/draw_scale_x) * eX + (1/draw_scale_y) * eY) * 12;
 		line = eY * fs_y;
-		sz_x = draw_TextWidth("  http://www.nexuiz.com/  ", 0) * fs_x;
+		sz_x = draw_TextWidth("  http://www.nexuiz.com/  ", 0, fs);
 		sz_y = 3 * fs_y;
 
 		draw_alpha = sin(time * 0.112 - 0.3) * 0.7;

Modified: trunk/data/qcsrc/server/cl_player.qc
===================================================================
--- trunk/data/qcsrc/server/cl_player.qc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/qcsrc/server/cl_player.qc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -998,7 +998,7 @@
 		lines = 0;
 		while(getWrappedLine_remaining && (!flood_lmax || lines <= flood_lmax))
 		{
-			msgstr = strcat(msgstr, " ", getWrappedLine(82.4289758859709, strlennocol)); // perl averagewidth.pl < gfx/vera-sans.width
+			msgstr = strcat(msgstr, " ", getWrappedLineLen(82.4289758859709, strlennocol)); // perl averagewidth.pl < gfx/vera-sans.width
 			++lines;
 		}
 		msgstr = substring(msgstr, 1, strlen(msgstr) - 1);

Modified: trunk/data/quake.rc
===================================================================
--- trunk/data/quake.rc	2010-01-24 12:53:27 UTC (rev 8545)
+++ trunk/data/quake.rc	2010-01-24 21:44:44 UTC (rev 8546)
@@ -4,6 +4,7 @@
 exec config_update.cfg
 exec autoexec.cfg
 stuffcmds
+exec loadfonts.cfg
 //startdemos demos/demo1 demos/demo2 demos/demo3
 //startdemos
 //play announcer/male/welcome.ogg



More information about the nexuiz-commits mailing list