~ubuntu-branches/ubuntu/lucid/gnome-subtitles/lucid

« back to all changes in this revision

Viewing changes to sublib-0.8/src/SubLib/Persistency/SubtitleOutput.cs

  • Committer: Bazaar Package Importer
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2007-12-03 20:52:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071203205252-2y6uuv4gcw9mi9n5
Tags: 0.7-1
* New upstream release;
* Add libxml-parser-perl to Build-Depends-Indep. Thanks to Lucas Nussbaum.
  (Closes: #445799);
* Fixes manpage issue with dpatch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of SubLib.
 
3
 * Copyright (C) 2005-2007 Pedro Castro
 
4
 *
 
5
 * SubLib 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 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * SubLib 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 this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
using System;
 
21
using System.Collections;
 
22
using System.Text;
 
23
using System.Text.RegularExpressions;
 
24
 
 
25
namespace SubLib {
 
26
 
 
27
internal class SubtitleOutput {
 
28
        private SubtitleFormat format = null;
 
29
        private SubtitleTextType textType = SubtitleTextType.Text;
 
30
        
 
31
        private Subtitle subtitle = null;
 
32
        private Subtitle previousSubtitle = null;
 
33
        private int subtitleNumber = 1;
 
34
        
 
35
        internal SubtitleOutput (SubtitleFormat format, SubtitleTextType textType) {
 
36
                this.format = format;
 
37
                this.textType = textType;
 
38
        }
 
39
 
 
40
        internal string Build (SubtitleCollection collection, SubtitleProperties subtitleProperties, FileProperties fileProperties) {
 
41
                StringBuilder output = new StringBuilder();
 
42
                if (format.HasHeaders)
 
43
                        output.Append(format.HeadersToString(subtitleProperties, fileProperties));
 
44
                
 
45
                if (format.HasBodyBegin)
 
46
                        output.Append(format.BodyBeginOut);
 
47
                
 
48
                string subtitleExpression = GetSubtitleExpression(format, subtitleProperties, fileProperties); 
 
49
                Regex fieldExpression = new Regex(@"<<(?<Field>\w+)(,(?<Width>\d+))?>>");
 
50
                MatchEvaluator matchEvaluator = new MatchEvaluator(this.FieldEvaluator);
 
51
 
 
52
                foreach (Subtitle currentSubtitle in collection) {
 
53
                        subtitle = currentSubtitle;
 
54
                        string outputSubtitle = fieldExpression.Replace(subtitleExpression, matchEvaluator);
 
55
                        output.Append(outputSubtitle);
 
56
                        output.Append("\n");
 
57
                        subtitleNumber++;
 
58
                        previousSubtitle = subtitle;
 
59
                }
 
60
                
 
61
                if (format.HasBodyEnd)
 
62
                        output.Append(format.BodyEndOut);
 
63
                
 
64
                subtitle = null;
 
65
                previousSubtitle = null;
 
66
                subtitleNumber = 1;
 
67
                
 
68
                ConvertNewlines(output, fileProperties);
 
69
                return output.ToString();
 
70
        }
 
71
 
 
72
        
 
73
        /* Private members */
 
74
 
 
75
        private string FieldEvaluator (Match match) {
 
76
                Group fieldGroup = match.Groups["Field"];
 
77
                string field = fieldGroup.Value;
 
78
                
 
79
                switch (field) {
 
80
                        case "StartFrame":
 
81
                                int startFrame = subtitle.Frames.Start;
 
82
                                return FormatedField(startFrame, match);
 
83
                        case "StartElapsedFrames":
 
84
                                int previousFrames = (previousSubtitle == null ? 0 : previousSubtitle.Frames.End);
 
85
                                int startElapsedFrames = subtitle.Frames.Start - previousFrames;
 
86
                                return FormatedField(startElapsedFrames, match);
 
87
                        case "EndFrame":
 
88
                                int endFrame = subtitle.Frames.End;
 
89
                                return FormatedField(endFrame, match);
 
90
                        case "EndElapsedFrames":
 
91
                                int endElapsedFrames = subtitle.Frames.Duration;
 
92
                                return FormatedField(endElapsedFrames, match);
 
93
                        case "StartHours":
 
94
                                int startHours = subtitle.Times.Start.Hours;
 
95
                                return FormatedField(startHours, 2, match);
 
96
                        case "StartMinutes":
 
97
                                int startMinutes = subtitle.Times.Start.Minutes;
 
98
                                return FormatedField(startMinutes, 2, match);
 
99
                        case "StartSeconds":
 
100
                                int startSeconds = subtitle.Times.Start.Seconds;
 
101
                                return FormatedField(startSeconds, 2, match);
 
102
                        case "StartDeciseconds":
 
103
                                int startDeciseconds = DivideAndRound(subtitle.Times.Start.Milliseconds, 100);
 
104
                                return FormatedField(startDeciseconds, 2, match);
 
105
                        case "StartTotalDeciseconds":
 
106
                                int startTotalDeciseconds = DivideAndRound((int)subtitle.Times.Start.TotalMilliseconds, 100);
 
107
                                return startTotalDeciseconds.ToString();
 
108
                        case "StartCentiseconds":
 
109
                                int startCentiseconds = DivideAndRound(subtitle.Times.Start.Milliseconds, 10);
 
110
                                return FormatedField(startCentiseconds, 2, match);
 
111
                        case "StartMilliseconds":
 
112
                                int startMilliseconds = subtitle.Times.Start.Milliseconds;
 
113
                                return FormatedField(startMilliseconds, 3, match);
 
114
                        case "StartMillisecondsAsFramesPAL":
 
115
                                int startMillisecondsAsFramesPAL = (int)Synchronization.TimeMillisecondsToFrames(subtitle.Times.Start.Milliseconds, 25);
 
116
                                return FormatedField(startMillisecondsAsFramesPAL, match);
 
117
                        case "StartMillisecondsAsFramesNTSC":
 
118
                                int startMillisecondsAsFramesNTSC = (int)Synchronization.TimeMillisecondsToFrames(subtitle.Times.Start.Milliseconds, 29.97F);
 
119
                                return FormatedField(startMillisecondsAsFramesNTSC, match);
 
120
                        case "EndMillisecondsAsFramesPAL":
 
121
                                int endMillisecondsAsFramesPAL = (int)Synchronization.TimeMillisecondsToFrames(subtitle.Times.End.Milliseconds, 25);
 
122
                                return FormatedField(endMillisecondsAsFramesPAL, match);
 
123
                        case "EndMillisecondsAsFramesNTSC":
 
124
                                int endMillisecondsAsFramesNTSC = (int)Synchronization.TimeMillisecondsToFrames(subtitle.Times.End.Milliseconds, 29.97F);
 
125
                                return FormatedField(endMillisecondsAsFramesNTSC, match);
 
126
                        case "StartElapsedTime":
 
127
                                TimeSpan previousTime = (previousSubtitle == null ? TimeSpan.Zero : previousSubtitle.Times.End);
 
128
                                TimeSpan startElapsedTime = subtitle.Times.Start - previousTime;
 
129
                                return FormatedField(startElapsedTime.TotalSeconds);
 
130
                        case "EndHours":
 
131
                                int endHours = subtitle.Times.End.Hours;
 
132
                                return FormatedField(endHours, 2, match);
 
133
                        case "EndMinutes":
 
134
                                int endMinutes = subtitle.Times.End.Minutes;
 
135
                                return FormatedField(endMinutes, 2, match);
 
136
                        case "EndSeconds":
 
137
                                int endSeconds = subtitle.Times.End.Seconds;
 
138
                                return FormatedField(endSeconds, 2, match);
 
139
                        case "EndDeciseconds":
 
140
                                int endDeciseconds = DivideAndRound(subtitle.Times.End.Milliseconds, 100);
 
141
                                return FormatedField(endDeciseconds, 2, match);
 
142
                        case "EndTotalDeciseconds":
 
143
                                int endTotalDeciseconds = DivideAndRound((int)subtitle.Times.End.TotalMilliseconds, 100);
 
144
                                return endTotalDeciseconds.ToString();
 
145
                        case "EndCentiseconds":
 
146
                                int endCentiseconds = DivideAndRound(subtitle.Times.End.Milliseconds, 10);
 
147
                                return FormatedField(endCentiseconds, 2, match);
 
148
                        case "EndMilliseconds":
 
149
                                int endMilliseconds = subtitle.Times.End.Milliseconds;
 
150
                                return FormatedField(endMilliseconds, 3, match);
 
151
                        case "EndElapsedTime":
 
152
                                TimeSpan endElapsedTime = subtitle.Times.Duration;
 
153
                                return FormatedField(endElapsedTime.TotalSeconds);
 
154
                        case "Text":
 
155
                                SubtitleText subtitleText = (textType == SubtitleTextType.Text ? subtitle.Text : subtitle.Translation);
 
156
                                string text = subtitleText.GetTrimLines(format.LineBreak);
 
157
                                return text.ToString();
 
158
                        case "Style":
 
159
                                string style = format.StyleToString(subtitle.Style);
 
160
                                return style.ToString();
 
161
                        case "EndOfStyle":
 
162
                                string endOfStyle = format.EndOfStyleToString(subtitle.Style);
 
163
                                return endOfStyle.ToString();
 
164
                        case "SubtitleNumber":
 
165
                                return FormatedField(subtitleNumber, match);
 
166
                        default:
 
167
                                return match.Value;
 
168
                }
 
169
        }
 
170
        
 
171
        private string FormatedField (int field, int defaultWidth, Match match) {
 
172
                Group group = match.Groups["Width"];
 
173
                int width = (group.Success ? Convert.ToInt32(group.Value) : defaultWidth);
 
174
                return DimensionField(field, width);
 
175
        }
 
176
        
 
177
        private string FormatedField (int field, Match match) {
 
178
                Group group = match.Groups["Width"];
 
179
                if (group.Success) {
 
180
                        int width = Convert.ToInt32(group.Value);
 
181
                        return DimensionField(field, width);
 
182
                }
 
183
                else
 
184
                        return field.ToString();        
 
185
        }
 
186
        
 
187
        private string FormatedField (double field) {
 
188
                return field.ToString("0.###");
 
189
        }
 
190
        
 
191
        private string DimensionField (int field, int width) {
 
192
                return field.ToString("D" + width).Substring(0, width);
 
193
        }
 
194
        
 
195
        private int DivideAndRound (int number, int denominator) {
 
196
                return (int)Math.Round((double)number / denominator);
 
197
        }
 
198
        
 
199
        private void ConvertNewlines (StringBuilder builder, FileProperties properties) {
 
200
                NewlineType type = properties.NewlineType;
 
201
                if ((type == NewlineType.Unknown) || (type == NewlineType.Unix))
 
202
                        return;
 
203
                
 
204
                string newline = (type == NewlineType.Windows ? "\r\n" : "\r"); //Windows : Macintosh
 
205
                builder.Replace("\n", newline);
 
206
        }
 
207
        
 
208
        private string GetSubtitleExpression (SubtitleFormat format, SubtitleProperties subtitleProperties, FileProperties fileProperties) {
 
209
                if (format.Mode == SubtitleMode.Both) {
 
210
                        if (fileProperties.TimingMode == TimingMode.Times)
 
211
                                return format.SubtitleOutTimesMode;
 
212
                        else
 
213
                                return format.SubtitleOutFramesMode;
 
214
                }
 
215
                else {
 
216
                        if (format.SubtitleOut != null)
 
217
                                return format.SubtitleOut;
 
218
                        else
 
219
                                return format.GetDynamicSubtitleOut(subtitleProperties);
 
220
                }       
 
221
        }
 
222
        
 
223
}
 
224
 
 
225
}