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> ¶ms, kryArray<int> ¶m_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