Fix a subtitle duplication issue, see Issue 22.
[xy_vsfilter.git] / src / subtitles / STS.h
blob6c0c2f5f2fa694ec757b1866693972b729c20a13
1 /*
2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #pragma once
24 #include <atlcoll.h>
25 #include <wxutil.h>
26 #include "TextFile.h"
27 #include "GFN.h"
29 typedef enum {TIME, FRAME} tmode; // the meaning of STSEntry::start/end
31 struct STSStyleBase
33 int charSet;
34 CString fontName;
35 double fontSize; // height
36 int fontWeight;
37 bool fItalic;
38 bool fUnderline;
39 bool fStrikeOut;
41 bool operator == (const STSStyleBase& s)const;
44 LOGFONTA& operator <<= (LOGFONTA& lfa, const STSStyleBase& s);
45 LOGFONTW& operator <<= (LOGFONTW& lfw, const STSStyleBase& s);
47 struct STSStyle: public STSStyleBase
49 public:
50 FwRect marginRect; // measured from the sides
51 int scrAlignment; // 1 - 9: as on the numpad, 0: default
52 int borderStyle; // 0: outline, 1: opaque box
53 double outlineWidthX, outlineWidthY;
54 double shadowDepthX, shadowDepthY;
55 COLORREF colors[4]; // usually: {primary, secondary, outline/background, shadow}
56 BYTE alpha[4];
58 double fontScaleX, fontScaleY; // percent
59 double fontSpacing; // +/- pixels
61 int fBlur;
62 double fGaussianBlur;
63 double fontAngleZ, fontAngleX, fontAngleY;
64 double fontShiftX, fontShiftY;
65 int relativeTo; // 0: window, 1: video, 2: undefined (~window)
67 STSStyle();
69 void SetDefault();
71 bool operator == (const STSStyle& s)const;
72 bool IsFontStyleEqual(const STSStyle& s) const;
74 void operator = (const LOGFONT& lf);
76 friend CString& operator <<= (CString& style, const STSStyle& s);
77 friend STSStyle& operator <<= (STSStyle& s, const CString& style);
80 typedef ::boost::flyweights::flyweight<STSStyle, ::boost::flyweights::no_locking> FwSTSStyle;
82 //for FwSTSStyle
83 static inline std::size_t hash_value(const STSStyleBase& s)
85 std::size_t hash = CStringElementTraits<CString>::Hash(s.fontName);
86 hash = (hash<<5) + (hash) + s.charSet;
87 hash = (hash<<5) + (hash) + hash_value(s.fontSize);
88 hash = (hash<<5) + (hash) + s.fontWeight;
89 hash = (hash<<5) + (hash) + s.fItalic; //Todo: fix me
90 hash = (hash<<5) + (hash) + s.fUnderline;
91 hash = (hash<<5) + (hash) + s.fStrikeOut;
92 return hash;
95 static inline std::size_t hash_value(const STSStyle& s)
97 //Todo: fix me
98 std::size_t hash = hash_value(static_cast<const STSStyleBase&>(s));
99 hash = (hash<<5) + (hash) + s.colors[0];
100 hash = (hash<<5) + (hash) + s.colors[2];
101 hash = (hash<<5) + (hash) + hash_value(s.fontScaleX);
102 hash = (hash<<5) + (hash) + hash_value(s.fontScaleY);
103 hash = (hash<<5) + (hash) + hash_value(s.fontAngleX);
104 hash = (hash<<5) + (hash) + hash_value(s.fontAngleY);
105 hash = (hash<<5) + (hash) + hash_value(s.fontAngleZ);
106 hash = (hash<<5) + (hash) + hash_value(s.fontShiftX);
107 hash = (hash<<5) + (hash) + hash_value(s.fontShiftY);
109 return hash;
112 class CSTSStyleMap : public CAtlMap<CString, STSStyle*, CStringElementTraits<CString> >
114 public:
115 CSTSStyleMap() {}
116 virtual ~CSTSStyleMap() {Free();}
117 void Free();
120 typedef struct
122 CStringW str;
123 bool fUnicode;
124 CString style, actor, effect;
125 CRect marginRect;
126 int layer;
127 int start, end;
128 int readorder;
129 } STSEntry;
131 class STSSegment
133 public:
134 int start, end;
135 bool animated; //if this segment has animate effect
136 CAtlArray<int> subs;
138 STSSegment() { animated=false; }
139 STSSegment(int s, int e) {start = s; end = e; animated = false;}
140 STSSegment(const STSSegment& stss) {*this = stss;}
141 void operator = (const STSSegment& stss) {start = stss.start; end = stss.end; animated = stss.animated; subs.Copy(stss.subs);}
144 class CSimpleTextSubtitle
146 friend class CSubtitleEditorDlg;
148 protected:
149 CAtlArray<STSEntry> m_entries;
150 CAtlArray<STSSegment> m_segments;
151 virtual void OnChanged() {}
153 public:
154 CString m_name;
155 tmode m_mode;
156 CTextFile::enc m_encoding;
157 CString m_path;
159 CSize m_dstScreenSize;
160 int m_defaultWrapStyle;
161 int m_collisions;
162 bool m_fScaledBAS;
164 bool m_fUsingAutoGeneratedDefaultStyle;
166 CSTSStyleMap m_styles;
168 enum EPARCompensationType
170 EPCTDisabled = 0,
171 EPCTDownscale = 1,
172 EPCTUpscale = 2,
173 EPCTAccurateSize = 3
176 EPARCompensationType m_ePARCompensationType;
177 double m_dPARCompensation;
179 public:
180 CSimpleTextSubtitle();
181 virtual ~CSimpleTextSubtitle();
183 virtual void Copy(CSimpleTextSubtitle& sts);
184 virtual void Empty();
186 bool IsEmpty();
188 void Sort(bool fRestoreReadorder = false);
189 void RemoveAllEntries();
190 void CreateSegments();
192 void Append(CSimpleTextSubtitle& sts, int timeoff = -1);
194 bool Open(CString fn, int CharSet, CString name = _T(""));
195 bool Open(CTextFile* f, int CharSet, CString name);
196 bool Open(BYTE* data, int len, int CharSet, CString name);
197 bool SaveAs(CString fn, exttype et, double fps = -1, CTextFile::enc = CTextFile::ASCII);
199 void Add(CStringW str, bool fUnicode, int start, int end, CString style = CString(_T("Default")),
200 const CString& actor = CString(_T("")),
201 const CString& effect = CString(_T("")),
202 const CRect& marginRect = CRect(0,0,0,0), int layer = 0, int readorder = -1);
203 //void Add(CStringW str, bool fUnicode, int start, int end, const CString& style, const CString& actor, const CString& effect, const CRect& marginRect, int layer, int readorder);
204 //void Add(CStringW str, bool fUnicode, int start, int end);
206 //add an STSEntry obj to the array
207 //NO addition segments added
208 //remember to call sort when all STSEntrys are ready
209 void AddSTSEntryOnly(CStringW str, bool fUnicode, int start, int end, CString style = _T("Default"), const CString& actor = _T(""), const CString& effect = _T(""), const CRect& marginRect = CRect(0,0,0,0), int layer = 0, int readorder = -1);
211 STSStyle* CreateDefaultStyle(int CharSet);
212 void ChangeUnknownStylesToDefault();
213 void AddStyle(CString name, STSStyle* style); // style will be stored and freed in Empty() later
214 bool CopyStyles(const CSTSStyleMap& styles, bool fAppend = false);
216 bool SetDefaultStyle(STSStyle& s);
217 bool GetDefaultStyle(STSStyle& s);
219 void ConvertToTimeBased(double fps);
220 void ConvertToFrameBased(double fps);
222 int TranslateStart(int i, double fps);
223 int TranslateEnd(int i, double fps);
224 int SearchSub(int t, double fps);
226 int TranslateSegmentStart(int i, double fps);
227 int TranslateSegmentEnd(int i, double fps);
228 void TranslateSegmentStartEnd(int i, double fps, /*out*/int& start, /*out*/int& end);
230 //find the first STSSegment with stop time > @t
231 //@iSegment: return the index, 0 based, of the STSSegment found, return STSSegments count if all STSSegments' stop time are NOT bigger than @t
232 //@nSegment: return the STSSegments count
233 //@return: the ptr to the STSSegment found, return NULL if such STSSegment not exist
234 const STSSegment* SearchSubs(int t, double fps, /*[out]*/ int* iSegment = NULL, int* nSegments = NULL);
236 //find STSSegment with a duration containing @t, i.e. with a start time <= @t and a stop time > @t
237 //@iSegment: return the index, 0 based, of the STSSegment found. Return -1 if such STSSegment not exist
238 //@nSegment: return the STSSegments count
239 //@return: the ptr to the STSSegment found, return NULL if such STSSegment not exist
240 STSSegment* SearchSubs2(int t, double fps, /*[out]*/ int* iSegment=NULL, int* nSegments=NULL);
242 const STSSegment* GetSegment(int iSegment) {return iSegment >= 0 && iSegment < (int)m_segments.GetCount() ? &m_segments[iSegment] : NULL;}
244 STSStyle* GetStyle(int i);
245 bool GetStyle(int i, STSStyle* const stss);
246 int GetCharSet(int i);
247 bool IsEntryUnicode(int i);
248 void ConvertUnicode(int i, bool fUnicode);
250 CStringA GetStrA(int i, bool fSSA = false);
251 CStringW GetStrW(int i, bool fSSA = false);
252 CStringW GetStrWA(int i, bool fSSA = false);
254 #ifdef UNICODE
255 #define GetStr GetStrW
256 #else
257 #define GetStr GetStrA
258 #endif
260 void SetStr(int i, CStringA str, bool fUnicode /* ignored */);
261 void SetStr(int i, CStringW str, bool fUnicode);
263 friend bool OpenMicroDVD(CTextFile* file, CSimpleTextSubtitle& ret, int CharSet);
266 extern BYTE CharSetList[];
267 extern TCHAR* CharSetNames[];
268 extern int CharSetLen;
270 class CHtmlColorMap : public CAtlMap<CString, DWORD, CStringElementTraits<CString> > {public: CHtmlColorMap();};
271 extern CHtmlColorMap g_colors;