Enable variable strength 'blur edges' effect, using other values than 1 to \be, like \be20. Also allow putting \be inside \t for animating the blur effect.

The parameter is the number of passes of blur to perform.

Originally committed to SVN as r2279.
This commit is contained in:
Niels Martin Hansen 2008-07-22 23:38:22 +00:00
parent 13654219c2
commit 5d3b1fe8c2
5 changed files with 41 additions and 37 deletions

View file

@ -1550,9 +1550,9 @@ bool CRenderedTextSubtitle::ParseSSATag(CSubtitle* sub, CStringW str, STSStyle&
}
else if(cmd == L"be")
{
int n = wcstol(p, NULL, 10);
int n = (int)(CalcAnimation(wcstol(p, NULL, 10), style.fBlur, fAnimate)+0.5);
style.fBlur = !p.IsEmpty()
? (n == 0 ? false : n == 1 ? true : org.fBlur)
? n
: org.fBlur;
}
else if(cmd == L"b")

View file

@ -679,7 +679,7 @@ void Rasterizer::DeleteOutlines()
mOutline.clear();
}
bool Rasterizer::Rasterize(int xsub, int ysub, bool fBlur)
bool Rasterizer::Rasterize(int xsub, int ysub, int fBlur)
{
_TrashOverlay();
@ -700,16 +700,17 @@ bool Rasterizer::Rasterize(int xsub, int ysub, bool fBlur)
mWideBorder = (mWideBorder+7)&~7;
if(!mWideOutline.empty())
if(!mWideOutline.empty() || fBlur)
{
width += 2*mWideBorder;
height += 2*mWideBorder;
// Expand the buffer a bit when we're blurring, since that can also widen the borders a bit
width += 2*mWideBorder + (fBlur ? 16 : 0);
height += 2*mWideBorder + (fBlur ? 16 : 0);
xsub += mWideBorder;
ysub += mWideBorder;
xsub += mWideBorder + (fBlur ? 8 : 0);
ysub += mWideBorder + (fBlur ? 8 : 0);
mOffsetX -= mWideBorder;
mOffsetY -= mWideBorder;
mOffsetX -= mWideBorder + (fBlur ? 8 : 0);
mOffsetY -= mWideBorder + (fBlur ? 8 : 0);
}
mOverlayWidth = ((width+7)>>3) + 1;
@ -760,32 +761,35 @@ bool Rasterizer::Rasterize(int xsub, int ysub, bool fBlur)
// If we're blurring, do a 3x3 box blur
// Can't do it on subpictures smaller than 3x3 pixels
if(fBlur && mOverlayWidth >= 3 && mOverlayHeight >= 3)
for (int pass = 0; pass < fBlur; pass++)
{
int pitch = mOverlayWidth*2;
byte* tmp = new byte[pitch*mOverlayHeight];
if(!tmp) return(false);
memcpy(tmp, mpOverlayBuffer, pitch*mOverlayHeight);
int border = !mWideOutline.empty() ? 1 : 0;
// This could be done in a separated way and win some speed
for(int j = 1; j < mOverlayHeight-1; j++)
if(mOverlayWidth >= 3 && mOverlayHeight >= 3)
{
byte* src = tmp + pitch*j + 2 + border;
byte* dst = mpOverlayBuffer + pitch*j + 2 + border;
int pitch = mOverlayWidth*2;
for(int i = 1; i < mOverlayWidth-1; i++, src+=2, dst+=2)
byte* tmp = new byte[pitch*mOverlayHeight];
if(!tmp) return(false);
memcpy(tmp, mpOverlayBuffer, pitch*mOverlayHeight);
int border = !mWideOutline.empty() ? 1 : 0;
// This could be done in a separated way and win some speed
for(int j = 1; j < mOverlayHeight-1; j++)
{
*dst = (src[-2-pitch] + (src[-pitch]<<1) + src[+2-pitch]
+ (src[-2]<<1) + (src[0]<<2) + (src[+2]<<1)
+ src[-2+pitch] + (src[+pitch]<<1) + src[+2+pitch]) >> 4;
}
}
byte* src = tmp + pitch*j + 2 + border;
byte* dst = mpOverlayBuffer + pitch*j + 2 + border;
delete [] tmp;
for(int i = 1; i < mOverlayWidth-1; i++, src+=2, dst+=2)
{
*dst = (src[-2-pitch] + (src[-pitch]<<1) + src[+2-pitch]
+ (src[-2]<<1) + (src[0]<<2) + (src[+2]<<1)
+ src[-2+pitch] + (src[+pitch]<<1) + src[+2+pitch]) >> 4;
}
}
delete [] tmp;
}
}
return true;

View file

@ -85,7 +85,7 @@ public:
bool ScanConvert();
bool CreateWidenedRegion(int borderX, int borderY);
void DeleteOutlines();
bool Rasterize(int xsub, int ysub, bool fBlur);
bool Rasterize(int xsub, int ysub, int fBlur);
CRect Draw(SubPicDesc& spd, CRect& clipRect, byte* pAlphaMask, int xsub, int ysub, const long* switchpts, bool fBody, bool fBorder);
};

View file

@ -1578,7 +1578,7 @@ static bool OpenXombieSub(CTextFile* file, CSimpleTextSubtitle& ret, int CharSet
style->fItalic = !!GetInt(buff);
style->fUnderline = !!GetInt(buff);
style->fStrikeOut = !!GetInt(buff);
style->fBlur = !!GetInt(buff);
style->fBlur = GetInt(buff) ? 1 : 0;
style->fontScaleX = GetFloat(buff);
style->fontScaleY = GetFloat(buff);
style->fontSpacing = GetFloat(buff);
@ -2906,7 +2906,7 @@ void STSStyle::SetDefault()
fItalic = false;
fUnderline = false;
fStrikeOut = false;
fBlur = false;
fBlur = 0;
fontShiftX = fontShiftY = fontAngleZ = fontAngleX = fontAngleY = 0;
relativeTo = 2;
}
@ -3004,7 +3004,7 @@ CString& operator <<= (CString& style, STSStyle& s)
s.colors[0], s.colors[1], s.colors[2], s.colors[3], s.alpha[0], s.alpha[1], s.alpha[2], s.alpha[3],
s.charSet,
s.fontName, s.fontSize, s.fontScaleX, s.fontScaleY, s.fontSpacing, s.fontWeight,
(int)s.fItalic, (int)s.fUnderline, (int)s.fStrikeOut, (int)s.fBlur,
(int)s.fItalic, (int)s.fUnderline, (int)s.fStrikeOut, s.fBlur,
s.fontAngleZ, s.fontAngleX, s.fontAngleY,
s.relativeTo);
@ -3027,7 +3027,7 @@ STSStyle& operator <<= (STSStyle& s, CString& style)
s.fontName = WToT(GetStr(str)); s.fontSize = GetFloat(str);
s.fontScaleX = GetFloat(str); s.fontScaleY = GetFloat(str);
s.fontSpacing = GetFloat(str); s.fontWeight = GetInt(str);
s.fItalic = !!GetInt(str); s.fUnderline = !!GetInt(str); s.fStrikeOut = !!GetInt(str); s.fBlur = !!GetInt(str);
s.fItalic = !!GetInt(str); s.fUnderline = !!GetInt(str); s.fStrikeOut = !!GetInt(str); s.fBlur = GetInt(str);
s.fontAngleZ = GetFloat(str); s.fontAngleX = GetFloat(str); s.fontAngleY = GetFloat(str);
s.relativeTo = GetInt(str);
}

View file

@ -49,7 +49,7 @@ public:
bool fItalic;
bool fUnderline;
bool fStrikeOut;
bool fBlur;
int fBlur;
double fontAngleZ, fontAngleX, fontAngleY;
double fontShiftX, fontShiftY;
int relativeTo; // 0: window, 1: video, 2: undefined (~window)