Move HTML canvas and tracks from ExceptionCode to Exception
[WebKit-https.git] / Source / WebCore / html / track / InbandGenericTextTrack.cpp
1 /*
2  * Copyright (C) 2012-2014 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "InbandGenericTextTrack.h"
28
29 #if ENABLE(VIDEO_TRACK)
30
31 #include "ExceptionCodePlaceholder.h"
32 #include "HTMLMediaElement.h"
33 #include "InbandTextTrackPrivate.h"
34 #include "Logging.h"
35 #include "VTTRegionList.h"
36 #include <math.h>
37 #include <wtf/text/CString.h>
38
39 namespace WebCore {
40
41 void GenericTextTrackCueMap::add(GenericCueData& cueData, TextTrackCueGeneric& cue)
42 {
43     m_dataToCueMap.add(&cueData, &cue);
44     m_cueToDataMap.add(&cue, &cueData);
45 }
46
47 TextTrackCueGeneric* GenericTextTrackCueMap::find(GenericCueData& cueData)
48 {
49     return m_dataToCueMap.get(&cueData);
50 }
51
52 GenericCueData* GenericTextTrackCueMap::find(TextTrackCue& cue)
53 {
54     return m_cueToDataMap.get(&cue);
55 }
56
57 void GenericTextTrackCueMap::remove(GenericCueData& cueData)
58 {
59     if (auto cue = m_dataToCueMap.take(&cueData))
60         m_cueToDataMap.remove(cue);
61 }
62
63 void GenericTextTrackCueMap::remove(TextTrackCue& cue)
64 {
65     if (auto data = m_cueToDataMap.take(&cue))
66         m_dataToCueMap.remove(data);
67 }
68
69 Ref<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
70 {
71     return adoptRef(*new InbandGenericTextTrack(context, client, playerPrivate));
72 }
73
74 InbandGenericTextTrack::InbandGenericTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
75     : InbandTextTrack(context, client, trackPrivate)
76 {
77 }
78
79 InbandGenericTextTrack::~InbandGenericTextTrack()
80 {
81 }
82
83 void InbandGenericTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, GenericCueData* cueData)
84 {
85     cue->willChange();
86
87     cue->setStartTime(cueData->startTime());
88     MediaTime endTime = cueData->endTime();
89     if (endTime.isPositiveInfinite() && mediaElement())
90         endTime = mediaElement()->durationMediaTime();
91     cue->setEndTime(endTime);
92     cue->setText(cueData->content());
93     cue->setId(cueData->id());
94     cue->setBaseFontSizeRelativeToVideoHeight(cueData->baseFontSize());
95     cue->setFontSizeMultiplier(cueData->relativeFontSize());
96     cue->setFontName(cueData->fontName());
97
98     if (cueData->position() > 0)
99         cue->setPosition(std::round(cueData->position()));
100     if (cueData->line() > 0)
101         cue->setLine(std::round(cueData->line()));
102     if (cueData->size() > 0)
103         cue->setSize(std::round(cueData->size()));
104     if (cueData->backgroundColor().isValid())
105         cue->setBackgroundColor(cueData->backgroundColor().rgb());
106     if (cueData->foregroundColor().isValid())
107         cue->setForegroundColor(cueData->foregroundColor().rgb());
108     if (cueData->highlightColor().isValid())
109         cue->setHighlightColor(cueData->highlightColor().rgb());
110
111     if (cueData->align() == GenericCueData::Start)
112         cue->setAlign(ASCIILiteral("start"));
113     else if (cueData->align() == GenericCueData::Middle)
114         cue->setAlign(ASCIILiteral("middle"));
115     else if (cueData->align() == GenericCueData::End)
116         cue->setAlign(ASCIILiteral("end"));
117     cue->setSnapToLines(false);
118
119     cue->didChange();
120 }
121
122 void InbandGenericTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, PassRefPtr<GenericCueData> prpCueData)
123 {
124     ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
125
126     RefPtr<GenericCueData> cueData = prpCueData;
127     if (m_cueMap.find(*cueData))
128         return;
129
130     RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(*scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
131     updateCueFromCueData(cue.get(), cueData.get());
132     if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
133         LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%s, end=%s, content=\"%s\"\n", toString(cueData->startTime()).utf8().data(), toString(cueData->endTime()).utf8().data(), cueData->content().utf8().data());
134         return;
135     }
136
137     LOG(Media, "InbandGenericTextTrack::addGenericCue added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime().toDouble(), cueData->endTime().toDouble(), cueData->content().utf8().data());
138
139     if (cueData->status() != GenericCueData::Complete)
140         m_cueMap.add(*cueData, *cue);
141
142     addCue(WTFMove(cue));
143 }
144
145 void InbandGenericTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
146 {
147     auto* cue = m_cueMap.find(*cueData);
148     if (!cue)
149         return;
150
151     updateCueFromCueData(cue, cueData);
152
153     if (cueData->status() == GenericCueData::Complete)
154         m_cueMap.remove(*cueData);
155 }
156
157 void InbandGenericTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
158 {
159     auto* cue = m_cueMap.find(*cueData);
160     if (cue) {
161         LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%s, end=%s, content=\"%s\"\n",  toString(cueData->startTime()).utf8().data(), toString(cueData->endTime()).utf8().data(), cueData->content().utf8().data());
162         removeCue(cue);
163     } else {
164         LOG(Media, "InbandGenericTextTrack::removeGenericCue UNABLE to find cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime().toDouble(), cueData->endTime().toDouble(), cueData->content().utf8().data());
165     }
166 }
167
168 ExceptionOr<void> InbandGenericTextTrack::removeCue(TextTrackCue* cue)
169 {
170     auto result = TextTrack::removeCue(cue);
171     if (!result.hasException() && cue)
172         m_cueMap.remove(*cue);
173     return result;
174 }
175
176 WebVTTParser& InbandGenericTextTrack::parser()
177 {
178     if (!m_webVTTParser)
179         m_webVTTParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), scriptExecutionContext());
180     return *m_webVTTParser;
181 }
182
183 void InbandGenericTextTrack::parseWebVTTCueData(InbandTextTrackPrivate* trackPrivate, const ISOWebVTTCue& cueData)
184 {
185     ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
186     parser().parseCueData(cueData);
187 }
188
189 void InbandGenericTextTrack::parseWebVTTFileHeader(InbandTextTrackPrivate* trackPrivate, String header)
190 {
191     ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
192     parser().parseFileHeader(header);
193 }
194
195 void InbandGenericTextTrack::newCuesParsed()
196 {
197     Vector<RefPtr<WebVTTCueData>> cues;
198     parser().getNewCues(cues);
199
200     for (auto& cueData : cues) {
201         auto vttCue = VTTCue::create(*scriptExecutionContext(), *cueData);
202
203         if (hasCue(vttCue.ptr(), TextTrackCue::IgnoreDuration)) {
204             LOG(Media, "InbandGenericTextTrack::newCuesParsed ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", vttCue->startTime(), vttCue->endTime(), vttCue->text().utf8().data());
205             return;
206         }
207         addCue(WTFMove(vttCue));
208     }
209 }
210
211 void InbandGenericTextTrack::newRegionsParsed()
212 {
213     Vector<RefPtr<VTTRegion>> newRegions;
214     parser().getNewRegions(newRegions);
215
216     for (auto& region : newRegions) {
217         region->setTrack(this);
218         regions()->add(region);
219     }
220 }
221
222 void InbandGenericTextTrack::fileFailedToParse()
223 {
224     LOG(Media, "Error parsing WebVTT stream.");
225 }
226
227 } // namespace WebCore
228
229 #endif