diff -u base/plugins/titler/title.C hvirtual-1.1.6/plugins/titler/title.C
--- base/plugins/titler/title.C	2003-05-16 12:55:10.000000000 +0200
+++ hvirtual-1.1.6/plugins/titler/title.C	2003-06-25 00:30:24.000000000 +0200
@@ -3,8 +3,6 @@
 // Andraz Tori <Andraz.tori1@guest.arnes.si>
 
 
-
-
 #include "clip.h"
 #include "colormodels.h"
 #include "filexml.h"
@@ -13,6 +11,10 @@
 #include "plugincolors.h"
 #include "title.h"
 #include "titlewindow.h"
+#include "freetype/ftglyph.h"
+#include "freetype/ftbbox.h"
+#include "freetype/ftoutln.h"
+#include "freetype/ftstroker.h"
 
 
 #include <errno.h>
@@ -35,6 +37,7 @@
 {
 	style = 0;
 	color = BLACK;
+	color_stroke = 0xff0000;
 	size = 24;
 	motion_strategy = NO_MOTION;
 	loop = 0;
@@ -50,6 +53,7 @@
 	sprintf(encoding, "ISO8859-1");
 	pixels_per_second = 1.0;
 	timecode = 0;
+	stroke_width = 1.0;
 }
 
 // Does not test equivalency but determines if redrawing text is necessary.
@@ -59,6 +63,8 @@
 		style == that.style &&
 		size == that.size &&
 		color == that.color &&
+		color_stroke == that.color_stroke &&
+		stroke_width == that.stroke_width &&
 		timecode == that.timecode && 
 		hjustification == that.hjustification &&
 		vjustification == that.vjustification &&
@@ -74,6 +80,8 @@
 	style = that.style;
 	size = that.size;
 	color = that.color;
+	color_stroke = that.color_stroke;
+	stroke_width = that.stroke_width;
 	pixels_per_second = that.pixels_per_second;
 	motion_strategy = that.motion_strategy;
 	loop = that.loop;
@@ -100,6 +108,8 @@
 	style = prev.style;
 	size = prev.size;
 	color = prev.color;
+	color_stroke = prev.color_stroke;
+	stroke_width = prev.stroke_width;
 	motion_strategy = prev.motion_strategy;
 	loop = prev.loop;
 	hjustification = prev.hjustification;
@@ -213,10 +223,6 @@
 
 
 
-
-
-
-
 GlyphPackage::GlyphPackage() : LoadPackage()
 {
 }
@@ -260,10 +266,12 @@
 
 	if(!result)
 	{
-
-		if(FT_Load_Char(freetype_face, glyph->char_code, FT_LOAD_RENDER))
+		int gindex = FT_Get_Char_Index(freetype_face, glyph->char_code);
+//		if(FT_Load_Char(freetype_face, glyph->char_code, FT_LOAD_RENDER))
+		if (gindex == 0) 
 		{
-			printf("GlyphUnit::process_package FT_Load_Char failed.\n");
+			if (glyph->char_code != 10)  // carrige return
+				printf("GlyphUnit::process_package FT_Load_Char failed - char: %i.\n",glyph->char_code);
 // Prevent a crash here
 			glyph->width = 8;
 			glyph->height = 8;
@@ -279,17 +287,91 @@
 				8);
 		}
 		else
+		if (plugin->config.stroke_width < 1.0/64) // effectively zero
 		{
-			glyph->width = freetype_face->glyph->bitmap.width;
-			glyph->height = freetype_face->glyph->bitmap.rows;
-			glyph->pitch = freetype_face->glyph->bitmap.pitch;
-			glyph->left = freetype_face->glyph->bitmap_left;
-			glyph->top = freetype_face->glyph->bitmap_top;
-			glyph->freetype_index = FT_Get_Char_Index(freetype_face, glyph->char_code);
-			glyph->advance_w = (freetype_face->glyph->advance.x >> 6);
-
+			FT_Glyph glyph_image;
+			FT_BBox bbox;
+			FT_Bitmap bm;
+			FT_Load_Glyph(freetype_face, gindex, FT_LOAD_DEFAULT);
+		    	FT_Get_Glyph(freetype_face->glyph, &glyph_image);
+			FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph_image)->outline, &bbox);
+//			printf("Stroke: Xmin: %ld, Xmax: %ld, Ymin: %ld, yMax: %ld\n",
+//					bbox.xMin,bbox.xMax, bbox.yMin, bbox.yMax);
+
+			FT_Outline_Translate(&((FT_OutlineGlyph) glyph_image)->outline,
+				- bbox.xMin,
+				- bbox.yMin);
+			glyph->width = bm.width = ((bbox.xMax - bbox.xMin + 63) >> 6);
+			glyph->height = bm.rows = ((bbox.yMax - bbox.yMin + 63) >> 6);
+			glyph->pitch = bm.pitch = bm.width;
+			bm.pixel_mode = FT_PIXEL_MODE_GRAY;
+			bm.num_grays = 256;
+			glyph->left = 0;
+			glyph->top = (bbox.yMax + 31) >>6;
+			glyph->freetype_index = gindex;
+			glyph->advance_w = ((freetype_face->glyph->advance.x + 31) >> 6);
 //printf("GlyphUnit::process_package 1 width=%d height=%d pitch=%d left=%d top=%d advance_w=%d freetype_index=%d\n", 
 //	glyph->width, glyph->height, glyph->pitch, glyph->left, glyph->top, glyph->advance_w, glyph->freetype_index);
+	
+			glyph->data = new VFrame(0,
+				glyph->width,
+				glyph->height,
+				BC_A8,
+				glyph->pitch);
+			glyph->data->clear_frame();
+			bm.buffer = glyph->data->get_data();
+			FT_Outline_Get_Bitmap( freetype_library,
+				&((FT_OutlineGlyph) glyph_image)->outline,
+				&bm);
+			glyph->data_stroke = NULL;
+			FT_Done_Glyph(glyph_image);
+		} else {
+			FT_Glyph glyph_image;
+			FT_Stroker stroker;
+			FT_Outline outline;
+			FT_Bitmap bm;
+			FT_BBox bbox, bbox_fill;
+			FT_UInt npoints, ncontours;	
+			typedef struct  FT_LibraryRec_ {    FT_Memory          memory; } FT_LibraryRec;
+			FT_Stroker_New(((FT_LibraryRec *)freetype_library)->memory, &stroker);
+			FT_Stroker_Set(stroker, (int)(plugin->config.stroke_width*64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
+			FT_Load_Glyph(freetype_face, gindex, FT_LOAD_DEFAULT);
+			FT_Get_Glyph(freetype_face->glyph, &glyph_image);
+			FT_Stroker_ParseOutline(stroker, &((FT_OutlineGlyph) glyph_image)->outline, 1);
+			FT_Stroker_GetCounts(stroker,&npoints, &ncontours);
+			FT_Outline_New(freetype_library, npoints, ncontours, &outline);
+			outline.n_points=0;
+			outline.n_contours=0;
+			FT_Stroker_Export (stroker, &outline);
+			FT_Outline_Get_BBox(&outline, &bbox);
+			FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph_image)->outline, &bbox_fill);
+		
+			FT_Outline_Translate(&outline,
+					- bbox.xMin,
+					- bbox.yMin + (int)(plugin->config.stroke_width*32));
+		
+			FT_Outline_Translate(&((FT_OutlineGlyph) glyph_image)->outline,
+					- bbox.xMin,
+					- bbox.yMin + (int)(plugin->config.stroke_width*32));
+//			printf("Stroke: Xmin: %ld, Xmax: %ld, Ymin: %ld, yMax: %ld\nFill	Xmin: %ld, Xmax: %ld, Ymin: %ld, yMax: %ld\n",
+//					bbox.xMin,bbox.xMax, bbox.yMin, bbox.yMax,
+//					bbox_fill.xMin,bbox_fill.xMax, bbox_fill.yMin, bbox_fill.yMax);
+	
+			glyph->width = bm.width = ((bbox.xMax - bbox.xMin) >> 6)+1;
+			glyph->height = bm.rows = ((bbox.yMax - bbox.yMin + (int)plugin->config.stroke_width*64) >> 6);
+			glyph->pitch = bm.pitch = bm.width;
+			bm.pixel_mode = FT_PIXEL_MODE_GRAY;
+			bm.num_grays = 256;
+			glyph->left = 0;
+			glyph->top = (bbox.yMax + 31) >>6;
+			glyph->freetype_index = gindex;
+			int real_advance = ((int)ceil((float)freetype_face->glyph->advance.x + plugin->config.stroke_width*64) >> 6);
+			glyph->advance_w = glyph->width + (int)ceil(plugin->config.stroke_width);
+			if (real_advance > glyph->advance_w) 
+				glyph->advance_w = real_advance;
+//printf("GlyphUnit::process_package 1 width=%d height=%d pitch=%d left=%d top=%d advance_w=%d freetype_index=%d\n", 
+//glyph->width, glyph->height, glyph->pitch, glyph->left, glyph->top, glyph->advance_w, glyph->freetype_index);
+
 
 //printf("GlyphUnit::process_package 1\n");
 			glyph->data = new VFrame(0,
@@ -297,14 +379,27 @@
 				glyph->height,
 				BC_A8,
 				glyph->pitch);
+			glyph->data_stroke = new VFrame(0,
+				glyph->width,
+				glyph->height,
+				BC_A8,
+				glyph->pitch);
+			glyph->data->clear_frame();
+			glyph->data_stroke->clear_frame();
+// for	debugging	memset(	glyph->data_stroke->get_data(), 40, glyph->pitch * glyph->height);
+			bm.buffer=glyph->data->get_data();
+			FT_Outline_Get_Bitmap( freetype_library,
+				&((FT_OutlineGlyph) glyph_image)->outline,
+				&bm);	
+			bm.buffer=glyph->data_stroke->get_data();
+			FT_Outline_Get_Bitmap( freetype_library,
+               		&outline,
+			&bm);
+			FT_Outline_Done(freetype_library,&outline);
+			FT_Stroker_Done(stroker);
+			FT_Done_Glyph(glyph_image);
 
 //printf("GlyphUnit::process_package 2\n");
-			for(int i = 0; i < glyph->height; i++)
-			{
-				memcpy(glyph->data->get_rows()[i], 
-					freetype_face->glyph->bitmap.buffer + glyph->pitch * i,
-					glyph->pitch);
-			}
 		}
 	}
 }
@@ -406,6 +501,12 @@
 			if(glyph->c == pkg->c)
 			{
 				draw_glyph(plugin->text_mask, glyph, pkg->x, pkg->y);
+				if (plugin->config.stroke_width >= 1.0/64) {
+					VFrame *tmp = glyph->data;
+					glyph->data = glyph->data_stroke;
+					draw_glyph(plugin->text_mask_stroke, glyph, pkg->x, pkg->y);
+					glyph->data = tmp;
+				}
 				break;
 			}
 		}
@@ -473,8 +574,6 @@
 
 
 
-
-
 #define TRANSLATE(type, max, components, r, g, b) \
 { \
 	unsigned char **in_rows = plugin->text_mask->get_rows(); \
@@ -560,6 +659,62 @@
 	} \
 }
 
+
+#define TRANSLATEA(type, max, components, r, g, b) \
+{ \
+	unsigned char **in_rows = plugin->text_mask->get_rows(); \
+	type **out_rows = (type**)plugin->output->get_rows(); \
+ \
+	for(int i = pkg->y1; i < pkg->y2; i++) \
+	{ \
+		if(i + server->out_y1_int >= 0 && \
+			i + server->out_y1_int < server->output_h) \
+		{ \
+			unsigned char *in_row = in_rows[i]; \
+			type *out_row = out_rows[i + server->out_y1_int]; \
+ \
+			for(int j = server->out_x1; j < server->out_x2_int; j++) \
+			{ \
+				if(j  >= 0 && \
+					j < server->output_w) \
+				{ \
+					int input = (int)(in_row[j - server->out_x1]);  \
+ \
+					input *= plugin->alpha; \
+/* Alpha is 0 - 256 */ \
+					input >>= 8; \
+ \
+					int anti_input = 0xff - input; \
+					if(components == 4) \
+					{ \
+						out_row[j * components + 0] =  \
+							(r * input + out_row[j * components + 0] * anti_input) / 0xff; \
+						out_row[j * components + 1] =  \
+							(g * input + out_row[j * components + 1] * anti_input) / 0xff; \
+						out_row[j * components + 2] =  \
+							(b * input + out_row[j * components + 2] * anti_input) / 0xff; \
+						if(max == 0xffff) \
+							out_row[j * components + 3] =  \
+								MAX((input << 8) | input, out_row[j * components + 3]); \
+						else \
+							out_row[j * components + 3] =  \
+								MAX(input, out_row[j * components + 3]); \
+					} \
+					else \
+					{ \
+						out_row[j * components + 0] =  \
+							(r * input + out_row[j * components + 0] * anti_input) / 0xff; \
+						out_row[j * components + 1] =  \
+							(g * input + out_row[j * components + 1] * anti_input) / 0xff; \
+						out_row[j * components + 2] =  \
+							(b * input + out_row[j * components + 2] * anti_input) / 0xff; \
+					} \
+				} \
+			} \
+		} \
+	} \
+}
+
 static YUV yuv;
 
 void TitleTranslateUnit::process_package(LoadPackage *package)
@@ -567,12 +722,19 @@
 	TitleTranslatePackage *pkg = (TitleTranslatePackage*)package;
 	TitleTranslate *server = (TitleTranslate*)this->server;
 	int r_in, g_in, b_in;
+	int r_in_stroke, g_in_stroke, b_in_stroke;
 
 //printf("TitleTranslateUnit::process_package 1 %d %d\n", pkg->y1, pkg->y2);
 
 	r_in = (plugin->config.color & 0xff0000) >> 16;
 	g_in = (plugin->config.color & 0xff00) >> 8;
 	b_in = plugin->config.color & 0xff;
+	if (plugin->config.stroke_width >= 1.0/64) {
+		r_in_stroke = (plugin->config.color_stroke & 0xff0000) >> 16;
+		g_in_stroke = (plugin->config.color_stroke & 0xff00) >> 8;
+		b_in_stroke = plugin->config.color_stroke & 0xff;
+	}
+
 	switch(plugin->output->get_color_model())
 	{
 		case BC_RGB888:
@@ -700,7 +862,7 @@
 
 //printf("TitleTranslate::init_packages 1\n");
 
-
+	
 	out_y1 = out_y1_int;
 	out_y2 = out_y2_int;
 	out_x1 = out_x1_int;
@@ -758,6 +920,7 @@
 // Build font database
 	build_fonts();
 	text_mask = 0;
+	text_mask_stroke = 0;
 	glyph_engine = 0;
 	title_engine = 0;
 	freetype_library = 0;
@@ -772,6 +935,7 @@
 //printf("TitleMain::~TitleMain 1\n");
 	PLUGIN_DESTRUCTOR_MACRO
 	if(text_mask) delete text_mask;
+	if(text_mask_stroke) delete text_mask_stroke;
 	if(char_positions) delete [] char_positions;
 	clear_glyphs();
 	if(glyph_engine) delete glyph_engine;
@@ -1131,7 +1295,7 @@
 
 int TitleMain::get_char_height()
 {
-	return config.size;
+	return config.size+ (int)ceil(config.stroke_width*2);
 }
 
 int TitleMain::get_char_advance(int current, int next)
@@ -1174,7 +1338,7 @@
 	else
 		kerning.x = 0;
 //printf("TitleMain::get_char_advance 2 %d %d\n", result, kerning.x);
-
+	
 	return result + (kerning.x >> 6);
 }
 
@@ -1482,6 +1646,7 @@
 	{
 		delete text_mask;
 		text_mask = 0;
+		text_mask_stroke = 0;
 	}
 
 	if(!text_mask)
@@ -1490,6 +1655,10 @@
 			text_w,
 			visible_rows * get_char_height(),
 			BC_A8);
+		text_mask_stroke = new VFrame(0,
+			text_w,
+			visible_rows * get_char_height(),
+			BC_A8);
 		need_redraw = 1;
 	}
 
@@ -1504,6 +1673,7 @@
 	{
 //printf("TitleMain::draw_mask 2\n");
 		text_mask->clear_frame();
+		text_mask_stroke->clear_frame();
 
 // for(int i = 0; i < text_mask->get_h(); i++)
 // 	for(int j = 0; j < text_mask->get_w(); j++)
@@ -1600,6 +1770,17 @@
 	{
 		if(!translate) translate = new TitleTranslate(this, PluginClient::smp + 1);
 		translate->process_packages();
+		if (config.stroke_width >= 1.0/64) 
+		{
+			int temp_color = config.color;
+			VFrame *tmp_text_mask = this->text_mask;
+			config.color = config.color_stroke;
+			this->text_mask = this->text_mask_stroke;
+
+			translate->process_packages();
+			config.color = temp_color;
+			this->text_mask = tmp_text_mask;
+		}
 	}
 //printf("TitleMain::overlay_mask 200\n");
 }
@@ -1670,7 +1851,9 @@
 	{
 //printf("TitleMain::process_realtime 2\n");
 		if(text_mask) delete text_mask;
+		if(text_mask_stroke) delete text_mask_stroke;
 		text_mask = 0;
+		text_mask_stroke = 0;
 //printf("TitleMain::process_realtime 2\n");
 		if(freetype_face) FT_Done_Face(freetype_face);
 		freetype_face = 0;
@@ -1793,6 +1976,8 @@
 	config.style = defaults->get("STYLE", (long)config.style);
 	config.size = defaults->get("SIZE", config.size);
 	config.color = defaults->get("COLOR", config.color);
+	config.color_stroke = defaults->get("COLOR_STROKE", config.color_stroke);
+	config.stroke_width = defaults->get("STROKE_WIDTH", config.stroke_width);
 	config.motion_strategy = defaults->get("MOTION_STRATEGY", config.motion_strategy);
 	config.loop = defaults->get("LOOP", config.loop);
 	config.pixels_per_second = defaults->get("PIXELS_PER_SECOND", config.pixels_per_second);
@@ -1836,6 +2021,8 @@
 	defaults->update("STYLE", (long)config.style);
 	defaults->update("SIZE", config.size);
 	defaults->update("COLOR", config.color);
+	defaults->update("COLOR_STROKE", config.color_stroke);
+	defaults->update("STROKE_WIDTH", config.stroke_width);
 	defaults->update("MOTION_STRATEGY", config.motion_strategy);
 	defaults->update("LOOP", config.loop);
 	defaults->update("PIXELS_PER_SECOND", config.pixels_per_second);
@@ -1935,6 +2122,8 @@
 	output.tag.set_property("STYLE", (long)config.style);
 	output.tag.set_property("SIZE", config.size);
 	output.tag.set_property("COLOR", config.color);
+	output.tag.set_property("COLOR_STROKE", config.color_stroke);
+	output.tag.set_property("STROKE_WIDTH", config.stroke_width);
 	output.tag.set_property("MOTION_STRATEGY", config.motion_strategy);
 	output.tag.set_property("LOOP", config.loop);
 	output.tag.set_property("PIXELS_PER_SECOND", config.pixels_per_second);
@@ -1984,6 +2173,8 @@
 				config.style = input.tag.get_property("STYLE", (long)config.style);
 				config.size = input.tag.get_property("SIZE", config.size);
 				config.color = input.tag.get_property("COLOR", config.color);
+				config.color_stroke = input.tag.get_property("COLOR_STROKE", config.color_stroke);
+				config.stroke_width = input.tag.get_property("STROKE_WIDTH", config.stroke_width);
 				config.motion_strategy = input.tag.get_property("MOTION_STRATEGY", config.motion_strategy);
 				config.loop = input.tag.get_property("LOOP", config.loop);
 				config.pixels_per_second = input.tag.get_property("PIXELS_PER_SECOND", config.pixels_per_second);
diff -u base/plugins/titler/title.h hvirtual-1.1.6/plugins/titler/title.h
--- base/plugins/titler/title.h	2003-05-16 12:55:10.000000000 +0200
+++ hvirtual-1.1.6/plugins/titler/title.h	2003-06-24 20:43:51.000000000 +0200
@@ -84,6 +84,7 @@
 	long style;
 	int size;
 	int color;
+	int color_stroke;
 // Motion of title across frame
 	int motion_strategy;
 // Loop motion path
@@ -108,6 +109,8 @@
 	char text[BCTEXTLEN];
 // Encoding to convert from 
 	char encoding[BCTEXTLEN];
+// Width of the stroke
+	double stroke_width;
 };
 
 class FontEntry
@@ -148,6 +151,7 @@
 	FT_ULong char_code;
 	int width, height, pitch, advance_w, left, top, freetype_index;
 	VFrame *data;
+	VFrame *data_stroke;
 };
 
 
@@ -358,6 +362,7 @@
 
 // Stage 1 parameters must be compared to redraw the text mask
 	VFrame *text_mask;
+	VFrame *text_mask_stroke;
 	GlyphEngine *glyph_engine;
 	TitleEngine *title_engine;
 	TitleTranslate *translate;
diff -u base/plugins/titler/titlewindow.C hvirtual-1.1.6/plugins/titler/titlewindow.C
--- base/plugins/titler/titlewindow.C	2003-05-16 12:55:10.000000000 +0200
+++ hvirtual-1.1.6/plugins/titler/titlewindow.C	2003-06-24 23:45:27.000000000 +0200
@@ -60,6 +60,7 @@
 	sizes.remove_all_objects();
 	encodings.remove_all_objects();
 	delete color_thread;
+	delete color_stroke_thread;
 	delete title_x;
 	delete title_y;
 }
@@ -244,6 +245,18 @@
 	color_y = y + 20;
 	color_thread = new TitleColorThread(client, this);
 
+	x = 265;
+	y += 50;
+	add_tool(strokewidth_title = new BC_Title(x, y, "Stroke width:"));
+	add_tool(stroke_width = new TitleFade(client, this, &client->config.stroke_width, x, y + 20));
+
+	x += 120;
+	add_tool(color_stroke_button = new TitleColorStrokeButton(client, this, x, y + 20));
+	color_stroke_x = color_x;
+	color_stroke_y = y + 20;
+	color_stroke_thread = new TitleColorStrokeThread(client, this);
+
+
 	x = 10;
 	y += 50;
 
@@ -296,6 +309,7 @@
 	encoding_title->reposition_window(encoding_title->get_x(), encoding_title->get_y());
 	encoding->reposition_window(encoding->get_x(), encoding->get_y());
 	color_button->reposition_window(color_button->get_x(), color_button->get_y());
+	color_stroke_button->reposition_window(color_stroke_button->get_x(), color_stroke_button->get_y());
 	motion_title->reposition_window(motion_title->get_x(), motion_title->get_y());
 	motion->reposition_window(motion->get_x(), motion->get_y());
 	loop->reposition_window(loop->get_x(), loop->get_y());
@@ -306,6 +320,8 @@
 	fadeout_title->reposition_window(fadeout_title->get_x(), fadeout_title->get_y());
 	fade_out->reposition_window(fade_out->get_x(), fade_out->get_y());
 	text_title->reposition_window(text_title->get_x(), text_title->get_y());
+	stroke_width->reposition_window(stroke_width->get_x(), stroke_width->get_y());
+	strokewidth_title->reposition_window(strokewidth_title->get_x(), strokewidth_title->get_y());
 	timecode->reposition_window(timecode->get_x(), timecode->get_y());
 
 	text->reposition_window(text->get_x(), 
@@ -381,6 +397,9 @@
 	set_color(client->config.color);
 	draw_box(color_x, color_y, 100, 30);
 	flash(color_x, color_y, 100, 30);
+	set_color(client->config.color_stroke);
+	draw_box(color_stroke_x, color_stroke_y, 100, 30);
+	flash(color_stroke_x, color_stroke_y, 100, 30);
 }
 
 void TitleWindow::update_justification()
@@ -406,6 +425,7 @@
 	dropshadow->update((float)client->config.dropshadow);
 	fade_in->update((float)client->config.fade_in);
 	fade_out->update((float)client->config.fade_out);
+	stroke_width->update((float)client->config.stroke_width);
 	font->update(client->config.font);
 	text->update(client->config.text);
 	speed->update(client->config.pixels_per_second);
@@ -522,6 +542,18 @@
 	return 1;
 }
 
+TitleColorStrokeButton::TitleColorStrokeButton(TitleMain *client, TitleWindow *window, int x, int y)
+ : BC_GenericButton(x, y, "Stroke color...")
+{
+	this->client = client;
+	this->window = window;
+}
+int TitleColorStrokeButton::handle_event()
+{
+	window->color_stroke_thread->start_window(client->config.color_stroke, 0);
+	return 1;
+}
+
 TitleMotion::TitleMotion(TitleMain *client, TitleWindow *window, int x, int y)
  : BC_PopupTextBox(window, 
 		&window->paths,
@@ -813,3 +845,18 @@
 	client->send_configure_change();
 	return 1;
 }
+TitleColorStrokeThread::TitleColorStrokeThread(TitleMain *client, TitleWindow *window)
+ : ColorThread()
+{
+	this->client = client;
+	this->window = window;
+}
+
+int TitleColorStrokeThread::handle_event(int output)
+{
+	client->config.color_stroke = output;
+	window->update_color();
+	window->flush();
+	client->send_configure_change();
+	return 1;
+}
diff -u base/plugins/titler/titlewindow.h hvirtual-1.1.6/plugins/titler/titlewindow.h
--- base/plugins/titler/titlewindow.h	2003-05-16 12:55:10.000000000 +0200
+++ hvirtual-1.1.6/plugins/titler/titlewindow.h	2003-06-24 23:37:29.000000000 +0200
@@ -35,6 +35,7 @@
 class TitleSize;
 class TitleEncoding;
 class TitleColorButton;
+class TitleColorStrokeButton;
 class TitleDropShadow;
 class TitleMotion;
 class TitleLoop;
@@ -50,6 +51,7 @@
 class TitleMid;
 class TitleBottom;
 class TitleColorThread;
+class TitleColorStrokeThread;
 class TitleSpeed;
 class TitleTimecode;
 
@@ -88,6 +90,8 @@
 	TitleEncoding *encoding;
 	TitleColorButton *color_button;
 	TitleColorThread *color_thread;
+	TitleColorStrokeButton *color_stroke_button;
+	TitleColorStrokeThread *color_stroke_thread;
 	BC_Title *motion_title;
 	TitleMotion *motion;
 	TitleLoop *loop;
@@ -95,6 +99,8 @@
 	TitleFade *fade_in;
 	BC_Title *fadeout_title;
 	TitleFade *fade_out;
+	BC_Title *strokewidth_title;
+	TitleFade *stroke_width;
 	BC_Title *text_title;
 	TitleText *text;
 	BC_Title *justify_title;
@@ -109,7 +115,7 @@
 	TitleTimecode *timecode;
 
 // Color preview
-	int color_x, color_y;
+	int color_x, color_y, color_stroke_x, color_stroke_y;
 	ArrayList<BC_ListBoxItem*> sizes;
 	ArrayList<BC_ListBoxItem*> encodings;
 	ArrayList<BC_ListBoxItem*> paths;
@@ -172,6 +178,14 @@
 	TitleMain *client;
 	TitleWindow *window;
 };
+class TitleColorStrokeButton : public BC_GenericButton
+{
+public:
+	TitleColorStrokeButton(TitleMain *client, TitleWindow *window, int x, int y);
+	int handle_event();
+	TitleMain *client;
+	TitleWindow *window;
+};
 class TitleMotion : public BC_PopupTextBox
 {
 public:
@@ -318,4 +332,13 @@
 	TitleWindow *window;
 };
 
+class TitleColorStrokeThread : public ColorThread
+{
+public:
+	TitleColorStrokeThread(TitleMain *client, TitleWindow *window);
+	int handle_event(int output);
+	TitleMain *client;
+	TitleWindow *window;
+};
+
 #endif
