Index: code/hud/hud.h
===================================================================
--- code/hud/hud.h	(revision 9982)
+++ code/hud/hud.h	(working copy)
@@ -14,6 +14,7 @@
 #include "graphics/2d.h"
 #include "hud/hudparse.h"
 #include "globalincs/vmallocator.h"
+#include "graphics/font.h"
 
 struct object;
 struct cockpit_display;
@@ -133,7 +134,7 @@
 void hud_start_text_flash(const char *txt, int t, int interval = 200);
 
 // convert a string to use mono spaced numbers
-void hud_num_make_mono(char *num_str);
+void hud_num_make_mono(char *num_str, int font_num = FONT1);
 
 // functions for handling hud animations
 void hud_anim_init(hud_anim *ha, int sx, int sy, const char *filename);
Index: code/hud/hudtarget.cpp
===================================================================
--- code/hud/hudtarget.cpp	(revision 9982)
+++ code/hud/hudtarget.cpp	(working copy)
@@ -5674,7 +5674,7 @@
 				delta_y = clip_h;
 			}
 
-			hud_num_make_mono(buf);
+			hud_num_make_mono(buf, font_num);
 
 			if ( Text_alignment ) {
 				gr_get_string_size(&w, &h, buf);
@@ -6018,7 +6018,7 @@
 			// get rid of #
 			end_string_at_first_hash_symbol(ammo_str);
 
-			hud_num_make_mono(ammo_str);
+			hud_num_make_mono(ammo_str, font_num);
 			gr_get_string_size(&w, &h, ammo_str);
 
 			renderString(position[0] + Weapon_pammo_offset_x - w, name_y, EG_NULL, ammo_str);
@@ -6094,7 +6094,7 @@
 	
 		// print out the ammo right justified
 		sprintf(ammo_str, "%d", ammo);
-		hud_num_make_mono(ammo_str);
+		hud_num_make_mono(ammo_str, font_num);
 		gr_get_string_size(&w, &h, ammo_str);
 
 		renderString(position[0] + Weapon_sammo_offset_x - w, name_y, EG_NULL, ammo_str);		
@@ -6454,7 +6454,7 @@
 
 	if (displayed_distance > 0.0f) {
 		sprintf(buf, "%d", fl2i(displayed_distance + 0.5f));
-		hud_num_make_mono(buf);
+		hud_num_make_mono(buf, font_num);
 		gr_get_string_size(&w, &h, buf);	
 	} else {
 		buf[0] = 0;
@@ -6639,7 +6639,7 @@
 		char ammo_str[32];
 
 		sprintf(ammo_str, "%d", ammo);
-		hud_num_make_mono(ammo_str);
+		hud_num_make_mono(ammo_str, font_num);
 
 		if ( Text_align ) {
 			int w, h;
@@ -6877,7 +6877,7 @@
 			// get rid of #
 			end_string_at_first_hash_symbol(ammo_str);
 
-			hud_num_make_mono(ammo_str);
+			hud_num_make_mono(ammo_str, font_num);
 			gr_get_string_size(&w, &h, ammo_str);
 
 			renderString(position[0] + _pammo_offset_x - w, position[1] + text_y_offset, EG_NULL, ammo_str);
@@ -7000,7 +7000,7 @@
 
 		// print out the ammo right justified
 		sprintf(ammo_str, "%d", ammo);
-		hud_num_make_mono(ammo_str);
+		hud_num_make_mono(ammo_str, font_num);
 		gr_get_string_size(&w, &h, ammo_str);
 
 		renderString(position[0] + _sammo_offset_x - w, position[1] + text_y_offset, EG_NULL, ammo_str);
Index: code/hud/hudnavigation.cpp
===================================================================
--- code/hud/hudnavigation.cpp	(revision 9982)
+++ code/hud/hudnavigation.cpp	(working copy)
@@ -15,7 +15,7 @@
 #include "hud/hudtargetbox.h"
 
 
-extern void hud_target_show_dist_on_bracket(int x, int y, float distance);
+extern void hud_target_show_dist_on_bracket(int x, int y, float distance, int font_num);
 extern void draw_brackets_square_quick(int x1, int y1, int x2, int y2, int thick);
 
 /**
Index: code/hud/hudshield.cpp
===================================================================
--- code/hud/hudshield.cpp	(revision 9982)
+++ code/hud/hudshield.cpp	(working copy)
@@ -1046,7 +1046,7 @@
 
 	sprintf(text_integrity, "%d", numeric_integrity);
 	if ( numeric_integrity < 100 ) {
-		hud_num_make_mono(text_integrity);
+		hud_num_make_mono(text_integrity, font_num);
 	}	
 
 	renderString(final_pos[0], final_pos[1], text_integrity);
Index: code/hud/hud.cpp
===================================================================
--- code/hud/hud.cpp	(revision 9982)
+++ code/hud/hud.cpp	(working copy)
@@ -691,7 +691,7 @@
 		char *text = new char[custom_text.size()+1];
 		strcpy(text, custom_text.c_str());
 
-		hud_num_make_mono(text);
+		hud_num_make_mono(text, font_num);
 		renderString(position[0] + textoffset_x, position[1] + textoffset_y, text);
 
 		delete[] text;
@@ -2073,7 +2073,7 @@
 			screen_integrity = 1;
 		}
 		sprintf(buf, XSTR( "%d%%", 219), screen_integrity);
-		hud_num_make_mono(buf);
+		hud_num_make_mono(buf, font_num);
 		gr_get_string_size(&w, &h, buf);
 		if ( screen_integrity < 30 ) {
 			gr_set_color_fast(&Color_red);
@@ -2187,7 +2187,7 @@
 		}
 
 		sprintf(buf, XSTR( "%d%%", 219), best_str);
-		hud_num_make_mono(buf);
+		hud_num_make_mono(buf, font_num);
 		gr_get_string_size(&w, &h, buf);
 		renderString(position[0] + subsys_integ_val_offset_x - w, sy, buf);
 		sy += line_h;
@@ -2311,12 +2311,18 @@
 /**
  * @brief Convert a number string to use mono-spaced 1 character
  */
-void hud_num_make_mono(char *num_str)
+void hud_num_make_mono(char *num_str, int font_num)
 {
-	int len, i, sc;
+	int len, i;
+	ubyte sc;
+
+	sc = lcl_get_font_index(font_num);
+	if (sc == 0) {
+		// specified font has no mono-spaced 1, make do with non-mono-spaced 1
+		return;
+	}
+
 	len = strlen(num_str);
-
-	sc = Lcl_special_chars;
 	for ( i = 0; i < len; i++ ) {
 		if ( num_str[i] == '1' ) {
 			num_str[i] = (char)(sc + 1);
Index: code/hud/hudreticle.cpp
===================================================================
--- code/hud/hudreticle.cpp	(revision 9982)
+++ code/hud/hudreticle.cpp	(working copy)
@@ -502,7 +502,7 @@
 			sprintf(buf, "%d", fl2i(desired_speed * Hud_speed_multiplier + 0.5f));
 		}
 
-		hud_num_make_mono(buf);
+		hud_num_make_mono(buf, font_num);
 		gr_get_string_size(&w, &h, buf);
 
 		renderString(position[0] + Target_speed_offsets[0] - w, position[1] + Target_speed_offsets[1], buf);
@@ -530,7 +530,7 @@
 
 	//setGaugeColor();
 	sprintf(buf, "%d", fl2i(current_speed+0.5f));
-	hud_num_make_mono(buf);
+	hud_num_make_mono(buf, font_num);
 	gr_get_string_size(&w, &h, buf);
 
 	if ( orbit ) {
Index: code/hud/hudbrackets.cpp
===================================================================
--- code/hud/hudbrackets.cpp	(revision 9982)
+++ code/hud/hudbrackets.cpp	(working copy)
@@ -385,7 +385,7 @@
 extern int Cmdline_targetinfo;
 
 // Display the current target distance, right justified at (x,y)
-void hud_target_show_dist_on_bracket(int x, int y, float distance)
+void hud_target_show_dist_on_bracket(int x, int y, float distance, int font_num)
 {
 	char	text_dist[64];
 	int	w,h;
@@ -403,7 +403,7 @@
 	displayed_distance = distance * Hud_unit_multiplier;
 
 	sprintf(text_dist, "%d", fl2i(displayed_distance+0.5f));
-	hud_num_make_mono(text_dist);
+	hud_num_make_mono(text_dist, font_num);
 	gr_get_string_size(&w,&h,text_dist);
 
 	int y_delta = 4;
@@ -877,7 +877,7 @@
 	}
 
 	// draw distance to target in lower right corner of box
-	hud_target_show_dist_on_bracket(x+(box_scale+10),y+(box_scale+10), dist);
+	hud_target_show_dist_on_bracket(x+(box_scale+10),y+(box_scale+10), dist, font_num);
 
 	// bring the scale back to normal
 	gr_reset_screen_scale();
@@ -925,7 +925,7 @@
 
 	// draw distance to target in lower right corner of box
 	if ( distance > 0 ) {
-		hud_target_show_dist_on_bracket(x2+w_correction,y2+h_correction,distance);
+		hud_target_show_dist_on_bracket(x2+w_correction,y2+h_correction,distance,font_num);
 	}
 
 	//	Maybe show + for each additional fighter or bomber attacking target.
Index: code/hud/hudtargetbox.cpp
===================================================================
--- code/hud/hudtargetbox.cpp	(revision 9982)
+++ code/hud/hudtargetbox.cpp	(working copy)
@@ -1113,7 +1113,7 @@
 		hy = fl2i(HUD_offset_y);
 
 		sprintf(outstr,XSTR( "d: %.0f", 340), dist);
-		hud_num_make_mono(outstr);
+		hud_num_make_mono(outstr, font_num);
 		gr_get_string_size(&w,&h,outstr);
 	
 		renderPrintf(position[0] + Dist_offsets[0]+hx, position[1] + Dist_offsets[1]+hy, EG_TBOX_DIST, outstr);
@@ -1806,7 +1806,7 @@
 	// print out the target distance and speed
 	sprintf(outstr,XSTR( "d: %.0f%s", 350), displayed_target_distance, modifiers[Player_ai->current_target_dist_trend]);
 
-	hud_num_make_mono(outstr);
+	hud_num_make_mono(outstr, font_num);
 	gr_get_string_size(&w,&h,outstr);
 
 	renderString(position[0] + Dist_offsets[0]+hx, position[1] + Dist_offsets[1]+hy, EG_TBOX_DIST, outstr);	
@@ -1835,7 +1835,7 @@
 	}
 
 	sprintf(outstr, XSTR( "s: %.0f%s", 351), displayed_target_speed, (displayed_target_speed>1)?modifiers[Player_ai->current_target_speed_trend]:"");
-	hud_num_make_mono(outstr);
+	hud_num_make_mono(outstr, font_num);
 
 	renderString(position[0] + Speed_offsets[0]+hx, position[1] + Speed_offsets[1]+hy, EG_TBOX_SPEED, outstr);
 
Index: code/localization/localize.h
===================================================================
--- code/localization/localize.h	(revision 9982)
+++ code/localization/localize.h	(working copy)
@@ -13,6 +13,7 @@
 #define __FREESPACE2_LOCALIZATION_UTILITIES_HEADER_FILE
 
 #include "globalincs/pstypes.h"
+#include "graphics/font.h"
 
 // ------------------------------------------------------------------------------------------------------------
 // LOCALIZE DEFINES/VARS
@@ -28,7 +29,9 @@
 typedef struct lang_info {
 	char lang_name[LCL_LANG_NAME_LEN + 1];				// literal name of the language
 	char lang_ext[LCL_LANG_NAME_LEN + 1];				// the extension used for adding to names on disk access
-	ubyte special_char_offset;							// where in the font do we have the special characters for this language
+	ubyte special_char_indexes[MAX_FONTS];				// where in the font do we have the special characters for this language
+														// note: treats 0 as "none" since a zero offset in a font makes no sense
+														// i.e. all the normal chars start at zero
 	int checksum;										// used for language auto-detection
 } lang_info;
 
@@ -70,6 +73,8 @@
 // set our current language
 void lcl_set_language(int lang);
 
+// get a fonts special characters index
+ubyte lcl_get_font_index(int font_num);
 
 // NOTE : generally you should only care about the above functions. Below are very low level functions
 //        which should already be well entrenched in FreeSpace. If you think you need to use one of the below
Index: code/localization/localize.cpp
===================================================================
--- code/localization/localize.cpp	(revision 9982)
+++ code/localization/localize.cpp	(working copy)
@@ -29,16 +29,16 @@
 
 // current language
 int Lcl_current_lang = FS2_OPEN_DEFAULT_LANGUAGE;
-SCP_vector<lang_info> Lcl_languages; 
+SCP_vector<lang_info> Lcl_languages;
 
 // These are the original languages supported by FS2. The code expects these languages to be supported even if the tables don't
 
 #define NUM_BUILTIN_LANGUAGES		4
 lang_info Lcl_builtin_languages[NUM_BUILTIN_LANGUAGES] = {
-	{ "English",		"",		127,	589986744},				// English
-	{ "German",			"gr",	164,	-1132430286 },			// German
-	{ "French",			"fr",	164,	0 },					// French
-	{ "Polish",			"pl",	127,	-1131728960},			// Polish
+	{ "English",		"",		{127,0,176,0,0},	589986744},				// English
+	{ "German",			"gr",	{164,0,176,0,0},	-1132430286 },			// German
+	{ "French",			"fr",	{164,0,176,0,0},	0 },					// French
+	{ "Polish",			"pl",	{127,0,176,0,0},	-1131728960},			// Polish
 };
 
 int Lcl_special_chars;
@@ -256,8 +256,17 @@
 			stuff_string(language.lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
 			required_string("+Extension:");
 			stuff_string(language.lang_ext, F_NAME, LCL_LANG_NAME_LEN + 1);
-			required_string("+Non-English Character Index:");
-			stuff_ubyte(&language.special_char_offset);
+			required_string("+Special Character Index:");
+			stuff_ubyte(&language.special_char_indexes[0]);
+			for (i = 1; i < MAX_FONTS; ++i) {
+				// default to "none"/0 except for font03 which defaults to 176
+				// NOTE: fonts.tbl may override these values
+				if (i == FONT3) {
+					language.special_char_indexes[i] = 176;
+				} else {
+					language.special_char_indexes[i] = 0;
+				}
+			}
 
 			lang_idx = -1;
 
@@ -265,7 +274,7 @@
 			for (i = 0; i < (int)Lcl_languages.size(); i++) {
 				if (!strcmp(Lcl_languages[i].lang_name, language.lang_name)) {
 					strcpy_s(Lcl_languages[i].lang_ext, language.lang_ext); 
-					Lcl_languages[i].special_char_offset = language.special_char_offset;
+					Lcl_languages[i].special_char_indexes[0] = language.special_char_indexes[0];
 					lang_idx = i;
 					break;
 				}
@@ -458,7 +467,7 @@
 	Assertion((Lcl_current_lang >= 0) && (Lcl_current_lang < (int)Lcl_languages.size()), "Attempt to set language to an invalid language");
 
 	// flag the proper language as being active
-	Lcl_special_chars = Lcl_languages[Lcl_current_lang].special_char_offset;
+	Lcl_special_chars = Lcl_languages[Lcl_current_lang].special_char_indexes[0];
 
 	// set to 0, so lcl_ext_open() knows to reset file pointers
 	Lcl_pointer_count = 0;
@@ -469,6 +478,14 @@
 	}
 }
 
+ubyte lcl_get_font_index(int font_num)
+{
+	Assertion((font_num >= 0) && (font_num < MAX_FONTS), "Passed an invalid font index");
+	Assertion((Lcl_current_lang >= 0) && (Lcl_current_lang < (int)Lcl_languages.size()), "Current language is not valid, can't get font indexes");
+
+	return Lcl_languages[Lcl_current_lang].special_char_indexes[font_num];
+}
+
 // maybe add on an appropriate subdirectory when opening a localized file
 void lcl_add_dir(char *current_path)
 {
Index: code/stats/stats.cpp
===================================================================
--- code/stats/stats.cpp	(revision 9982)
+++ code/stats/stats.cpp	(working copy)
@@ -221,7 +221,7 @@
 
          // mission kills stats
 			sprintf(text,"%d",Active_player->stats.kill_count_ok + add.kill_count_ok);
-			hud_num_make_mono(text);
+			hud_num_make_mono(text, gr_get_current_fontnum());
 			gr_printf(sx,sy,text);
 			sy += 2*dy;
          // alltime primary weapon stats
