From 5d21970bbc9c63c928235ea1c62ac4127cc23100 Mon Sep 17 00:00:00 2001
From: Niels Martin Hansen <nielsm@aegisub.org>
Date: Mon, 9 Jul 2007 16:00:10 +0000
Subject: [PATCH] Added known VSFilter patches.

Originally committed to SVN as r1398.
---
 vsfilter/clipbug-patch-take3.patch | 160 +++++++++++++++++++++
 vsfilter/csriapi.cpp               | 221 +++++++++++++++++++++++++++++
 vsfilter/fax_fay-SVN611.patch      |  68 +++++++++
 vsfilter/floatpos.patch            |  41 ++++++
 vsfilter/fontcrash.patch           |  49 +++++++
 vsfilter/readme.txt                |  16 +++
 6 files changed, 555 insertions(+)
 create mode 100644 vsfilter/clipbug-patch-take3.patch
 create mode 100644 vsfilter/csriapi.cpp
 create mode 100644 vsfilter/fax_fay-SVN611.patch
 create mode 100644 vsfilter/floatpos.patch
 create mode 100644 vsfilter/fontcrash.patch
 create mode 100644 vsfilter/readme.txt

diff --git a/vsfilter/clipbug-patch-take3.patch b/vsfilter/clipbug-patch-take3.patch
new file mode 100644
index 000000000..9fc2b8645
--- /dev/null
+++ b/vsfilter/clipbug-patch-take3.patch
@@ -0,0 +1,160 @@
+Index: Rasterizer.cpp
+===================================================================
+--- Rasterizer.cpp	(revision 611)
++++ Rasterizer.cpp	(working copy)
+@@ -771,21 +771,22 @@
+ 
+ ///////////////////////////////////////////////////////////////////////////
+ 
+-#define pixmix(s) {																 \
+-	int a = (((s)*(color>>24))>>6)&0xff;										 \
+-	int ia = 256-a;																 \
+-																				 \
+-	dst[wt] = ((((dst[wt]&0x00ff00ff)*ia + (color&0x00ff00ff)*a)&0xff00ff00)>>8) \
+-			| ((((dst[wt]&0x0000ff00)*ia + (color&0x0000ff00)*a)&0x00ff0000)>>8) \
+-			| ((((dst[wt]>>8)&0x00ff0000)*ia)&0xff000000);						 \
+-	} \
++static __forceinline void pixmix(DWORD *dst, DWORD color, DWORD alpha)
++{
++	int a = (((alpha)*(color>>24))>>12)&0xff;
++	int ia = 256-a;
+ 
++	*dst = ((((*dst&0x00ff00ff)*ia + (color&0x00ff00ff)*a)&0xff00ff00)>>8)
++			| ((((*dst&0x0000ff00)*ia + (color&0x0000ff00)*a)&0x00ff0000)>>8)
++			| ((((*dst>>8)&0x00ff0000)*ia)&0xff000000);
++}
++
+ #include <xmmintrin.h>
+ #include <emmintrin.h>
+ 
+ static __forceinline void pixmix_sse2(DWORD* dst, DWORD color, DWORD alpha)
+ {
+-	alpha = ((alpha * (color>>24)) >> 6) & 0xff;
++	alpha = ((alpha * (color>>24)) >> 12) & 0xff;
+ 	color &= 0xffffff;
+ 
+ 	__m128i zero = _mm_setzero_si128();
+@@ -850,13 +851,13 @@
+ 			{
+ 				if(fBody)
+ 				{
+-					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, s[wt*2]);
+-					else for(int wt=0; wt<w; ++wt) pixmix(s[wt*2]);
++					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, s[wt*2]<<6);
++					else for(int wt=0; wt<w; ++wt) pixmix(&dst[wt], color, s[wt*2]<<6);
+ 				}
+ 				else
+ 				{
+-					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, src[wt*2+1] - src[wt*2]);
+-					else for(int wt=0; wt<w; ++wt) pixmix(src[wt*2+1] - src[wt*2]);
++					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, (src[wt*2+1] - src[wt*2])<<6);
++					else for(int wt=0; wt<w; ++wt) pixmix(&dst[wt], color, (src[wt*2+1] - src[wt*2])<<6);
+ 				}
+ 			}
+ 			else
+@@ -869,13 +870,13 @@
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+ 						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];}
+-						pixmix_sse2(&dst[wt], color, s[wt*2]);
++						pixmix_sse2(&dst[wt], color, s[wt*2]<<6);
+ 					}
+ 					else
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+ 						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];}
+-						pixmix(s[wt*2]);
++						pixmix(&dst[wt], color, s[wt*2]<<6);
+ 					}
+ 				}
+ 				else
+@@ -884,13 +885,13 @@
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+ 						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];} 
+-						pixmix_sse2(&dst[wt], color, src[wt*2+1] - src[wt*2]);
++						pixmix_sse2(&dst[wt], color, (src[wt*2+1] - src[wt*2])<<6);
+ 					}
+ 					else
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+ 						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];} 
+-						pixmix(src[wt*2+1] - src[wt*2]);
++						pixmix(&dst[wt], color, (src[wt*2+1] - src[wt*2])<<6);
+ 					}
+ 				}
+ 			}
+@@ -901,13 +902,21 @@
+ 			{
+ 				if(fBody)
+ 				{
+-					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, s[wt*2] * am[wt]);
+-					else for(int wt=0; wt<w; ++wt) pixmix(s[wt*2] * am[wt]);
++					if(fSSE2)
++						for(int wt=0; wt<w; ++wt)
++							pixmix_sse2(&dst[wt], color, s[wt*2] * am[wt]);
++					else
++						for(int wt=0; wt<w; ++wt)
++							pixmix(&dst[wt], color, s[wt*2] * am[wt]);
+ 				}
+ 				else
+ 				{
+-					if(fSSE2) for(int wt=0; wt<w; ++wt) pixmix_sse2(&dst[wt], color, (src[wt*2+1] - src[wt*2]) * am[wt]);
+-					else for(int wt=0; wt<w; ++wt) pixmix((src[wt*2+1] - src[wt*2]) * am[wt]);
++					if(fSSE2)
++						for(int wt=0; wt<w; ++wt)
++							pixmix_sse2(&dst[wt], color, (src[wt*2+1] - src[wt*2]) * am[wt]);
++					else
++						for(int wt=0; wt<w; ++wt)
++							pixmix(&dst[wt], color, (src[wt*2+1] - src[wt*2]) * am[wt]);
+ 				}
+ 			}
+ 			else
+@@ -919,14 +928,20 @@
+ 					if(fSSE2) 
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+-						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];}
++						if(wt+xo >= sw[1]) {
++							while(wt+xo >= sw[1])
++								sw += 2; color = sw[-2];
++						}
+ 						pixmix_sse2(&dst[wt], color, s[wt*2] * am[wt]);
+ 					}
+ 					else
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+-						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];}
+-						pixmix(s[wt*2] * am[wt]);
++						if(wt+xo >= sw[1]) {
++							while(wt+xo >= sw[1])
++								sw += 2; color = sw[-2];
++						}
++						pixmix(&dst[wt], color, s[wt*2] * am[wt]);
+ 					}
+ 				}
+ 				else
+@@ -934,14 +949,20 @@
+ 					if(fSSE2) 
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+-						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];} 
++						if(wt+xo >= sw[1]) {
++							while(wt+xo >= sw[1])
++								sw += 2; color = sw[-2];
++						} 
+ 						pixmix_sse2(&dst[wt], color, (src[wt*2+1] - src[wt*2]) * am[wt]);
+ 					}
+ 					else
+ 					for(int wt=0; wt<w; ++wt)
+ 					{
+-						if(wt+xo >= sw[1]) {while(wt+xo >= sw[1]) sw += 2; color = sw[-2];} 
+-						pixmix((src[wt*2+1] - src[wt*2]) * am[wt]);
++						if(wt+xo >= sw[1]) {
++							while(wt+xo >= sw[1])
++								sw += 2; color = sw[-2];
++						} 
++						pixmix(&dst[wt], color, (src[wt*2+1] - src[wt*2]) * am[wt]);
+ 					}
+ 				}
+ 			}
diff --git a/vsfilter/csriapi.cpp b/vsfilter/csriapi.cpp
new file mode 100644
index 000000000..c6b722981
--- /dev/null
+++ b/vsfilter/csriapi.cpp
@@ -0,0 +1,221 @@
+/* 
+ *	Copyright (C) 2007 Niels Martin Hansen
+ *	http://aegisub.net/
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "stdafx.h"
+#include <afxdlgs.h>
+#include <atlpath.h>
+#include "resource.h"
+#include "..\..\..\subtitles\VobSubFile.h"
+#include "..\..\..\subtitles\RTS.h"
+#include "..\..\..\subtitles\SSF.h"
+#include "..\..\..\SubPic\MemSubPic.h"
+
+// Be sure to have <csri/csri.h> in include path
+#define CSRIAPI extern "C" __declspec(dllexport)
+#define CSRI_OWN_HANDLES
+typedef const char *csri_rend;
+extern "C" struct csri_vsfilter_inst {
+	CRenderedTextSubtitle *rts;
+	CCritSec *cs;
+	CSize script_res;
+	CSize screen_res;
+	CRect video_rect;
+	enum csri_pixfmt pixfmt;
+	size_t readorder;
+};
+typedef struct csri_vsfilter_inst csri_inst;
+#include <csri/csri.h>
+static csri_rend csri_vsfilter = "vsfilter";
+
+
+CSRIAPI csri_inst *csri_open_file(csri_rend *renderer, const char *filename, struct csri_openflag *flags)
+{
+	int namesize;
+	wchar_t *namebuf;
+
+	namesize = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
+	if (!namesize)
+		return 0;
+	namesize++;
+	namebuf = new wchar_t[namesize];
+	MultiByteToWideChar(CP_UTF8, 0, filename, -1, namebuf, namesize);
+
+	csri_inst *inst = new csri_inst();
+	inst->cs = new CCritSec();
+	inst->rts = new CRenderedTextSubtitle(inst->cs);
+	if (inst->rts->Open(CString(namebuf), DEFAULT_CHARSET)) {
+		delete[] namebuf;
+		inst->readorder = 0;
+		return inst;
+	} else {
+		delete[] namebuf;
+		delete inst->rts;
+		delete inst->cs;
+		delete inst;
+		return 0;
+	}
+}
+
+
+CSRIAPI csri_inst *csri_open_mem(csri_rend *renderer, const void *data, size_t length, struct csri_openflag *flags)
+{
+	// This is actually less effecient than opening a file, since this first writes the memory data to a temp file,
+	// then opens that file and parses from that.
+	csri_inst *inst = new csri_inst();
+	inst->cs = new CCritSec();
+	inst->rts = new CRenderedTextSubtitle(inst->cs);
+	if (inst->rts->Open((BYTE*)data, (int)length, DEFAULT_CHARSET, _T("CSRI memory subtitles"))) {
+		inst->readorder = 0;
+		return inst;
+	} else {
+		delete inst->rts;
+		delete inst->cs;
+		delete inst;
+		return 0;
+	}
+}
+
+
+CSRIAPI void csri_close(csri_inst *inst)
+{
+	if (!inst) return;
+
+	delete inst->rts;
+	delete inst->cs;
+	delete inst;
+}
+
+
+CSRIAPI int csri_request_fmt(csri_inst *inst, const struct csri_fmt *fmt)
+{
+	if (!inst) return -1;
+
+	if (!fmt->width || !fmt->height)
+		return -1;
+
+	// Check if pixel format is supported
+	switch (fmt->pixfmt) {
+		case CSRI_F_BGR_:
+		case CSRI_F_BGR:
+		case CSRI_F_YUY2:
+		case CSRI_F_YV12:
+			inst->pixfmt = fmt->pixfmt;
+			break;
+
+		default:
+			return -1;
+	}
+	inst->screen_res = CSize(fmt->width, fmt->height);
+	inst->video_rect = CRect(0, 0, fmt->width, fmt->height);
+	return 0;
+}
+
+
+CSRIAPI void csri_render(csri_inst *inst, struct csri_frame *frame, double time)
+{
+	const double arbitrary_framerate = 25.0;
+	SubPicDesc spd;
+	spd.w = inst->screen_res.cx;
+	spd.h = inst->screen_res.cy;
+	switch (inst->pixfmt) {
+		case CSRI_F_BGR_:
+			spd.type = MSP_RGB32;
+			spd.bpp = 32;
+			spd.bits = frame->planes[0];
+			spd.pitch = frame->strides[0];
+			break;
+
+		case CSRI_F_BGR:
+			spd.type = MSP_RGB24;
+			spd.bpp = 24;
+			spd.bits = frame->planes[0];
+			spd.pitch = frame->strides[0];
+			break;
+
+		case CSRI_F_YUY2:
+			spd.type = MSP_YUY2;
+			spd.bpp = 16;
+			spd.bits = frame->planes[0];
+			spd.pitch = frame->strides[0];
+			break;
+
+		case CSRI_F_YV12:
+			spd.type = MSP_YV12;
+			spd.bpp = 12;
+			spd.bits = frame->planes[0];
+			spd.bitsU = frame->planes[1];
+			spd.bitsV = frame->planes[2];
+			spd.pitch = frame->strides[0];
+			spd.pitchUV = frame->strides[1];
+			break;
+
+		default:
+			// eh?
+			return;
+	}
+	spd.vidrect = inst->video_rect;
+
+	inst->rts->Render(spd, (REFERENCE_TIME)(time*10000000), arbitrary_framerate, inst->video_rect);
+}
+
+
+// No extensions supported
+CSRIAPI void *csri_query_ext(csri_rend *rend, csri_ext_id extname)
+{
+	return 0;
+}
+
+// Get info for renderer
+static struct csri_info csri_vsfilter_info = {
+	"vsfilter_textsub", // name
+	"2.38-0611-3", // version (assumed version number, svn revision, patchlevel)
+	// 2.38-0611 is base svn 611
+	// 2.38-0611-1 is with clipfix and fax/fay patch
+	// 2.38-0611-2 adds CSRI
+	// 2.38-0611-3 fixes a bug in CSRI and adds fontcrash-fix and float-pos
+	"VSFilter/TextSub (SVN 611 + patches for clipfix, fax/fay, fontcrash-fix, float-pos and CSRI)", // longname
+	"Gabest", // author
+	"Copyright (c) 2004-2007 by Gabest and others" // copyright
+};
+CSRIAPI struct csri_info *csri_renderer_info(csri_rend *rend)
+{
+	return &csri_vsfilter_info;
+}
+// Only one supported, obviously
+CSRIAPI csri_rend *csri_renderer_byname(const char *name, const char *specific)
+{
+	if (strcmp(name, csri_vsfilter_info.name))
+		return 0;
+	if (specific && strcmp(specific, csri_vsfilter_info.specific))
+		return 0;
+	return &csri_vsfilter;
+}
+// Still just one
+CSRIAPI csri_rend *csri_renderer_default()
+{
+	return &csri_vsfilter;
+}
+// And no further
+CSRIAPI csri_rend *csri_renderer_next(csri_rend *prev)
+{
+	return 0;
+}
+
diff --git a/vsfilter/fax_fay-SVN611.patch b/vsfilter/fax_fay-SVN611.patch
new file mode 100644
index 000000000..9dab8148e
--- /dev/null
+++ b/vsfilter/fax_fay-SVN611.patch
@@ -0,0 +1,68 @@
+Index: STS.h
+===================================================================
+--- STS.h	(revision 611)
++++ STS.h	(working copy)
+@@ -49,6 +49,7 @@
+ 	bool	fStrikeOut;
+ 	bool	fBlur;
+ 	double	fontAngleZ, fontAngleX, fontAngleY;
++	double	fontShiftX, fontShiftY;
+ 	int		relativeTo; // 0: window, 1: video, 2: undefined (~window)
+ 
+ 	STSStyle();
+Index: RTS.cpp
+===================================================================
+--- RTS.cpp	(revision 611)
++++ RTS.cpp	(working copy)
+@@ -156,8 +156,8 @@
+ 	{
+ 		double x, y, z, xx, yy, zz;
+ 
+-		x = scalex * mpPathPoints[i].x - org.x;
+-		y = scaley * mpPathPoints[i].y - org.y;
++		x = scalex * (mpPathPoints[i].x + m_style.fontShiftX * mpPathPoints[i].y) - org.x;
++		y = scaley * (mpPathPoints[i].y + m_style.fontShiftY * mpPathPoints[i].x) - org.y;
+ 		z = 0;
+ 
+ 		xx = x*caz + y*saz;
+@@ -1437,6 +1437,8 @@
+ 			params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
+ 		else if(!cmd.Find(L"frx") || !cmd.Find(L"fry") || !cmd.Find(L"frz"))
+ 			params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
++		else if(!cmd.Find(L"fax") || !cmd.Find(L"fay"))
++			params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
+ 		else if(!cmd.Find(L"fr"))
+ 			params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
+ 		else if(!cmd.Find(L"fscx") || !cmd.Find(L"fscy"))
+@@ -1618,6 +1620,18 @@
+ 				}
+ 			}
+ 		}
++		else if(cmd == L"fax")
++		{
++			style.fontShiftX = !p.IsEmpty()
++				? CalcAnimation(wcstod(p, NULL), style.fontShiftX, fAnimate)
++				: org.fontShiftX;
++		}
++		else if(cmd == L"fay")
++		{
++			style.fontShiftY = !p.IsEmpty()
++				? CalcAnimation(wcstod(p, NULL), style.fontShiftY, fAnimate)
++				: org.fontShiftY;
++		}
+ 		else if(cmd == L"fe")
+ 		{
+ 			int n = wcstol(p, NULL, 10);
+Index: STS.cpp
+===================================================================
+--- STS.cpp	(revision 611)
++++ STS.cpp	(working copy)
+@@ -2898,7 +2898,7 @@
+ 	fUnderline = false;
+ 	fStrikeOut = false;
+ 	fBlur = false;
+-	fontAngleZ = fontAngleX = fontAngleY = 0;
++	fontShiftX = fontShiftY = fontAngleZ = fontAngleX = fontAngleY = 0;
+ 	relativeTo = 2;
+ }
+ 
diff --git a/vsfilter/floatpos.patch b/vsfilter/floatpos.patch
new file mode 100644
index 000000000..ba88a41ac
--- /dev/null
+++ b/vsfilter/floatpos.patch
@@ -0,0 +1,41 @@
+Index: RTS.cpp
+===================================================================
+--- RTS.cpp	(revision 611)
++++ RTS.cpp	(working copy)
+@@ -1724,10 +1738,10 @@
+ 			{
+ 				if(Effect* e = new Effect)
+ 				{
+-					e->param[0] = (int)(sub->m_scalex*wcstol(params[0], NULL, 10)*8);
+-					e->param[1] = (int)(sub->m_scaley*wcstol(params[1], NULL, 10)*8);
+-					e->param[2] = (int)(sub->m_scalex*wcstol(params[2], NULL, 10)*8);
+-					e->param[3] = (int)(sub->m_scaley*wcstol(params[3], NULL, 10)*8);
++					e->param[0] = (int)(sub->m_scalex*wcstod(params[0], NULL)*8);
++					e->param[1] = (int)(sub->m_scaley*wcstod(params[1], NULL)*8);
++					e->param[2] = (int)(sub->m_scalex*wcstod(params[2], NULL)*8);
++					e->param[3] = (int)(sub->m_scaley*wcstod(params[3], NULL)*8);
+ 
+ 					e->t[0] = e->t[1] = -1;
+ 
+@@ -1747,8 +1761,8 @@
+ 			{
+ 				if(Effect* e = new Effect)
+ 				{
+-					e->param[0] = (int)(sub->m_scalex*wcstol(params[0], NULL, 10)*8);
+-					e->param[1] = (int)(sub->m_scaley*wcstol(params[1], NULL, 10)*8);
++					e->param[0] = (int)(sub->m_scalex*wcstod(params[0], NULL)*8);
++					e->param[1] = (int)(sub->m_scaley*wcstod(params[1], NULL)*8);
+ 
+ 					sub->m_effects[EF_ORG] = e;
+ 				}
+@@ -1764,8 +1778,8 @@
+ 			{
+ 				if(Effect* e = new Effect)
+ 				{
+-					e->param[0] = e->param[2] = (int)(sub->m_scalex*wcstol(params[0], NULL, 10)*8);
+-					e->param[1] = e->param[3] = (int)(sub->m_scaley*wcstol(params[1], NULL, 10)*8);
++					e->param[0] = e->param[2] = (int)(sub->m_scalex*wcstod(params[0], NULL)*8);
++					e->param[1] = e->param[3] = (int)(sub->m_scaley*wcstod(params[1], NULL)*8);
+ 					e->t[0] = e->t[1] = 0;
+ 
+ 					sub->m_effects[EF_MOVE] = e;
diff --git a/vsfilter/fontcrash.patch b/vsfilter/fontcrash.patch
new file mode 100644
index 000000000..f9c90e0ca
--- /dev/null
+++ b/vsfilter/fontcrash.patch
@@ -0,0 +1,49 @@
+Index: filters/transform/vsfilter/DirectVobSub.cpp
+
+===================================================================
+
+--- filters/transform/vsfilter/DirectVobSub.cpp	(revision 611)
+
++++ filters/transform/vsfilter/DirectVobSub.cpp	(working copy)
+
+@@ -231,9 +231,9 @@
+
+ 	if(lf)
+ 	{
+ 		if(lflen == sizeof(LOGFONTA))
+-			strcpy(((LOGFONTA*)lf)->lfFaceName, CStringA(m_defStyle.fontName));
++			strncpy_s(((LOGFONTA*)lf)->lfFaceName, LF_FACESIZE, CStringA(m_defStyle.fontName), _TRUNCATE);
+ 		else if(lflen == sizeof(LOGFONTW))
+-			wcscpy(((LOGFONTW*)lf)->lfFaceName, CStringW(m_defStyle.fontName));
++			wcsncpy_s(((LOGFONTW*)lf)->lfFaceName, LF_FACESIZE, CStringW(m_defStyle.fontName), _TRUNCATE);
+ 		else
+ 			return E_INVALIDARG;
+ 
+Index: subtitles/STS.cpp
+
+===================================================================
+
+--- subtitles/STS.cpp	(revision 611)
+
++++ subtitles/STS.cpp	(working copy)
+
+@@ -2957,7 +2957,7 @@
+
+ LOGFONTA& operator <<= (LOGFONTA& lfa, STSStyle& s)
+ {
+ 	lfa.lfCharSet = s.charSet;
+-	strcpy_s(lfa.lfFaceName, CStringA(s.fontName));
++	strncpy_s(lfa.lfFaceName, LF_FACESIZE, CStringA(s.fontName), _TRUNCATE);
+ 	HDC hDC = GetDC(0);
+ 	lfa.lfHeight = -MulDiv((int)(s.fontSize+0.5), GetDeviceCaps(hDC, LOGPIXELSY), 72);
+ 	ReleaseDC(0, hDC);
+@@ -2971,7 +2971,7 @@
+
+ LOGFONTW& operator <<= (LOGFONTW& lfw, STSStyle& s)
+ {
+ 	lfw.lfCharSet = s.charSet;
+-	wcscpy_s(lfw.lfFaceName, CStringW(s.fontName));
++	wcsncpy_s(lfw.lfFaceName, LF_FACESIZE, CStringW(s.fontName), _TRUNCATE);
+ 	HDC hDC = GetDC(0);
+ 	lfw.lfHeight = -MulDiv((int)(s.fontSize+0.5), GetDeviceCaps(hDC, LOGPIXELSY), 72);
+ 	ReleaseDC(0, hDC);
\ No newline at end of file
diff --git a/vsfilter/readme.txt b/vsfilter/readme.txt
new file mode 100644
index 000000000..6c0320aad
--- /dev/null
+++ b/vsfilter/readme.txt
@@ -0,0 +1,16 @@
+This directory contains a collection of patches for the Subtitles and
+VSFilter code on the guliverkli Subversion repository. All the patches
+are again revision 611.
+
+guliverkli svn: https://guliverkli.svn.sourceforge.net/svnroot/guliverkli
+
+Patches applied in guliverkli/src/subtitles/:
+  clipbug-patch-take3.patch
+  fax_fay-SVN611.patch
+  floatpos.patch
+
+Patch applied in guliverkli/src/filters/transform/vsfilter/:
+  fontcrash.patch
+
+File added to guliverkli/src/filters/transform/vsfilter/:
+  csriapi.cpp  [also add to project file]
-- 
GitLab