1 /*
2  *	Copyright (C) 2004-2005 Vadim Berezniker
3  *	http://www.kryptolus.com
4  *
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.
9  *
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.
14  *
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
19  *
20  */
21 #include "stdafx.h"
22 
23 #include "common.h"
24 
25 #include "sabbu.h"
26 
27 #include "kryString.h"
28 
29 #include "kryArray.h"
30 
31 #include "krySSACommandParser.h"
32 
33 
34 extern struct sabbu app;
35 
ParseParameterList(kryString & param,kryArray<kryString> & params,kryArray<int> & param_offsets,int offset)36 void krySSACommandParser::ParseParameterList(kryString & param, kryArray<kryString> & params, kryArray<int> & param_offsets, int offset)
37 {
38   while(!param.IsEmpty())
39   {
40     int i = param.Find(','), j = param.Find('\\');
41 
42     if(i >= 0 && (j < 0 || i < j))
43     {
44       kryString s = param.Left(i);
45       if(!s.IsEmpty())
46       {
47         this->OnCommandParameter(s);
48       }
49 
50       if(!s.Trim().IsEmpty())
51       {
52         params.Add(s.Trim());
53         param_offsets.Add(offset);
54       }
55 
56       offset += (i + 1);
57       param = param.Mid(i+1);
58       this->OnCommandParameterSeparator(",");
59     }
60     else
61     {
62       this->OnCommandParameter(param);
63       param_offsets.Add(offset);
64       param.Trim();
65       if(!param.IsEmpty())
66         params.Add(param);
67 
68       param.Empty();
69     }
70   }
71 }
72 
ParseCommandIntoParameters(kryString & cmd,kryArray<kryString> & params,kryArray<int> & param_offsets,int offset)73 void krySSACommandParser::ParseCommandIntoParameters(kryString & cmd, kryArray<kryString> &params, kryArray<int> &param_offsets, int offset)
74 {
75   cmd = cmd.Mid(1);
76   offset++;
77 
78   if(!cmd.Find("1c") || !cmd.Find("2c") || !cmd.Find("3c") || !cmd.Find("4c"))
79   {
80     params.Add(cmd.Mid(2).Trim("&H")), cmd = cmd.Left(2);
81     param_offsets.Add(offset + 2);
82   }
83   else if(!cmd.Find("1a") || !cmd.Find("2a") || !cmd.Find("3a") || !cmd.Find("4a"))
84   {
85     params.Add(cmd.Mid(2).Trim("&H")), cmd = cmd.Left(2);
86     param_offsets.Add(offset + 2);
87   }
88   else if(!cmd.Find("alpha"))
89   {
90     params.Add(cmd.Mid(5).Trim("&H")), cmd = cmd.Left(5);
91     param_offsets.Add(offset + 5);
92   }
93   else if(!cmd.Find("an"))
94   {
95     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
96     param_offsets.Add(offset + 2);
97   }
98   else if(!cmd.Find("a"))
99   {
100     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
101     param_offsets.Add(offset + 1);
102   }
103   else if(!cmd.Find("bord"))
104   {
105     params.Add(cmd.Mid(4)), cmd = cmd.Left(4);
106     param_offsets.Add(offset + 4);
107   }
108   else if(!cmd.Find("be"))
109   {
110     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
111     param_offsets.Add(offset + 2);
112   }
113   else if(!cmd.Find("b"))
114   {
115     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
116     param_offsets.Add(offset + 1);
117   }
118   else if(!cmd.Find("clip"))
119     ;
120   else if(!cmd.Find("c"))
121   {
122     params.Add(cmd.Mid(1).Trim("&H")), cmd = cmd.Left(1);
123     param_offsets.Add(offset + 1);
124   }
125   else if(!cmd.Find("fade"))
126     ;
127   else if(!cmd.Find("fe"))
128   {
129     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
130     param_offsets.Add(offset + 2);
131   }
132   else if(!cmd.Find("fn"))
133   {
134     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
135     param_offsets.Add(offset + 2);
136   }
137   else if(!cmd.Find("frx") || !cmd.Find("fry") || !cmd.Find("frz"))
138   {
139     params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
140     param_offsets.Add(offset + 3);
141   }
142   else if(!cmd.Find("fr"))
143   {
144     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
145     param_offsets.Add(offset + 2);
146   }
147   else if(!cmd.Find("fscx") || !cmd.Find("fscy"))
148   {
149     params.Add(cmd.Mid(4)), cmd = cmd.Left(4);
150     param_offsets.Add(offset + 4);
151   }
152   else if(!cmd.Find("fsc"))
153   {
154     params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
155     param_offsets.Add(offset + 3);
156   }
157   else if(!cmd.Find("fsp"))
158   {
159     params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
160     param_offsets.Add(offset + 3);
161   }
162   else if(!cmd.Find("fs"))
163   {
164     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
165     param_offsets.Add(offset + 2);
166   }
167   else if(!cmd.Find("i"))
168   {
169     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
170     param_offsets.Add(offset + 1);
171   }
172   else if(!cmd.Find("kf") || !cmd.Find("ko"))
173   {
174     params.Add(cmd.Mid(2)), cmd = cmd.Left(2);
175     param_offsets.Add(offset + 2);
176   }
177   else if(!cmd.Find("k") || !cmd.Find("K"))
178   {
179     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
180     param_offsets.Add(offset + 1);
181   }
182   else if(!cmd.Find("move"))
183     ;
184   else if(!cmd.Find("org"))
185     ;
186   else if(!cmd.Find("pbo"))
187   {
188     params.Add(cmd.Mid(3)), cmd = cmd.Left(3);
189     param_offsets.Add(offset + 3);
190   }
191   else if(!cmd.Find("pos"))
192     ;
193   else if(!cmd.Find("p"))
194   {
195     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
196     param_offsets.Add(offset + 1);
197   }
198   else if(!cmd.Find("q"))
199   {
200     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
201     param_offsets.Add(offset + 1);
202   }
203   else if(!cmd.Find("r"))
204   {
205     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
206     param_offsets.Add(offset + 1);
207   }
208   else if(!cmd.Find("shad"))
209   {
210     params.Add(cmd.Mid(4)), cmd = cmd.Left(4);
211     param_offsets.Add(offset + 4);
212   }
213   else if(!cmd.Find("s"))
214   {
215     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
216     param_offsets.Add(offset + 1);
217   }
218   else if(!cmd.Find("t"))
219     ;
220   else if(!cmd.Find("u"))
221   {
222     params.Add(cmd.Mid(1)), cmd = cmd.Left(1);
223     param_offsets.Add(offset + 1);
224   }
225 }
226 
ParseSSATag(kryString str,int offset,gboolean in_parenthesis)227 void krySSACommandParser::ParseSSATag(kryString str, int offset, gboolean in_parenthesis)
228 {
229   this->OnCommandGroupStart(in_parenthesis ? "{" : "", offset - 1);
230 
231   int prev_command_end = 0;
232   gunichar c;
233   int i, j;
234 
235   for(i = 0; ; i = j)
236   {
237     j = str.Find('\\', i);
238 
239     if(j == -1 && prev_command_end != str.GetLength())
240     {
241       kryString unparsed = str.Mid(prev_command_end);
242       this->OnCommandUnparsed(unparsed);
243     }
244 
245     if(j == -1)
246       break;
247 
248     if(prev_command_end < j)
249     {
250       kryString unparsed = str.Mid(prev_command_end, j - prev_command_end);
251       this->OnCommandUnparsed(unparsed);
252     }
253 
254     int cmd_start = j;
255     kryString cmd;
256     for(c = str[j]; c && c != '(' && (cmd.GetLength() == 0 || c != '\\'); cmd += c, c = str[++j]);
257     if(cmd.GetLength() == 1) continue;
258 
259     this->OnCommandText(cmd);
260 
261     kryArray<kryString> params;
262     kryArray<int> param_offsets;
263 
264     if(str[j] == '(')
265     {
266       this->OnCommandParameterStart("(");
267 
268       kryString param;
269       int param_list_start = j + 1;
270       for(c = str[++j]; c && c != ')'; param += c, c = str[++j]);
271       this->ParseParameterList(param, params, param_offsets, offset + param_list_start);
272 
273       if(c == ')')
274       {
275         this->OnCommandParameterEnd(")");
276         j++;
277       }
278 
279     }
280 
281     this->ParseCommandIntoParameters(cmd, params, param_offsets, offset + cmd_start);
282 
283     this->OnCommandEnd();
284 
285     this->OnCommand(cmd, offset + cmd_start, j - cmd_start, params, param_offsets);
286     prev_command_end = j;
287   }
288 
289   this->OnCommandGroupEnd(in_parenthesis ? "}" : "", str.GetLength());
290 }
291 
ParseSubtitleString(kryString str)292 void krySSACommandParser::ParseSubtitleString(kryString str)
293 {
294   int offset = 0;
295   while(!str.IsEmpty())
296   {
297     bool notTag = true;
298 
299     int i;
300 
301     if(str[0] == '{' && (i = str.Find('}')) > 0)
302     {
303       ParseSSATag(str.Mid(1, i-1), offset + 1, TRUE);
304       str = str.Mid(i+1);
305       offset += (i + 1);
306       notTag = false;
307     }
308 
309     i = str.Find('{');
310     if(i < 0) i = str.GetLength();
311     if(i == 0 && notTag) i++;
312 
313 
314     kryString text = str.Left(i);
315     OnString(text, offset);
316 
317     str = str.Mid(i);
318     offset += i;
319   }
320 }
321