ca39dabab93e8f4594cfe2324c91b18187d74bd5
[WebKit-https.git] / Source / WebCore / html / track / InbandGenericTextTrack.cpp
1 /*
2  * Copyright (C) 2012 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
28 #if ENABLE(VIDEO_TRACK)
29
30 #include "InbandGenericTextTrack.h"
31
32 #include "ExceptionCodePlaceholder.h"
33 #include "HTMLMediaElement.h"
34 #include "InbandTextTrackPrivate.h"
35 #include "Logging.h"
36 #include <math.h>
37 #include <wtf/text/CString.h>
38
39 namespace WebCore {
40
41 GenericTextTrackCueMap::GenericTextTrackCueMap()
42 {
43 }
44
45 GenericTextTrackCueMap::~GenericTextTrackCueMap()
46 {
47 }
48
49 void GenericTextTrackCueMap::add(GenericCueData* cueData, TextTrackCueGeneric* cue)
50 {
51     m_dataToCueMap.add(cueData, cue);
52     m_cueToDataMap.add(cue, cueData);
53 }
54
55 PassRefPtr<TextTrackCueGeneric> GenericTextTrackCueMap::find(GenericCueData* cueData)
56 {
57     CueDataToCueMap::iterator iter = m_dataToCueMap.find(cueData);
58     if (iter == m_dataToCueMap.end())
59         return 0;
60
61     return iter->value;
62 }
63
64 PassRefPtr<GenericCueData> GenericTextTrackCueMap::find(TextTrackCue* cue)
65 {
66     CueToDataMap::iterator iter = m_cueToDataMap.find(cue);
67     if (iter == m_cueToDataMap.end())
68         return 0;
69
70     return iter->value;
71 }
72
73 void GenericTextTrackCueMap::remove(GenericCueData* cueData)
74 {
75     RefPtr<TextTrackCueGeneric> cue = find(cueData);
76
77     if (cue)
78         m_cueToDataMap.remove(cue);
79     m_dataToCueMap.remove(cueData);
80 }
81
82 void GenericTextTrackCueMap::remove(TextTrackCue* cue)
83 {
84     RefPtr<GenericCueData> genericData = find(cue);
85     if (genericData) {
86         m_dataToCueMap.remove(genericData);
87         m_cueToDataMap.remove(cue);
88     }
89 }
90
91 PassRefPtr<InbandGenericTextTrack> InbandGenericTextTrack::create(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> playerPrivate)
92 {
93     return adoptRef(new InbandGenericTextTrack(context, client, playerPrivate));
94 }
95
96 InbandGenericTextTrack::InbandGenericTextTrack(ScriptExecutionContext* context, TextTrackClient* client, PassRefPtr<InbandTextTrackPrivate> trackPrivate)
97     : InbandTextTrack(context, client, trackPrivate)
98 {
99 }
100
101 InbandGenericTextTrack::~InbandGenericTextTrack()
102 {
103 }
104
105 void InbandGenericTextTrack::updateCueFromCueData(TextTrackCueGeneric* cue, GenericCueData* cueData)
106 {
107     cue->willChange();
108
109     cue->setStartTime(cueData->startTime(), IGNORE_EXCEPTION);
110     double endTime = cueData->endTime();
111     if (std::isinf(endTime) && mediaElement())
112         endTime = mediaElement()->duration();
113     cue->setEndTime(endTime, IGNORE_EXCEPTION);
114     cue->setText(cueData->content());
115     cue->setId(cueData->id());
116     cue->setBaseFontSizeRelativeToVideoHeight(cueData->baseFontSize());
117     cue->setFontSizeMultiplier(cueData->relativeFontSize());
118     cue->setFontName(cueData->fontName());
119
120     if (cueData->position() > 0)
121         cue->setPosition(lround(cueData->position()), IGNORE_EXCEPTION);
122     if (cueData->line() > 0)
123         cue->setLine(lround(cueData->line()), IGNORE_EXCEPTION);
124     if (cueData->size() > 0)
125         cue->setSize(lround(cueData->size()), IGNORE_EXCEPTION);
126     if (cueData->backgroundColor().isValid())
127         cue->setBackgroundColor(cueData->backgroundColor().rgb());
128     if (cueData->foregroundColor().isValid())
129         cue->setForegroundColor(cueData->foregroundColor().rgb());
130     if (cueData->highlightColor().isValid())
131         cue->setHighlightColor(cueData->highlightColor().rgb());
132
133     if (cueData->align() == GenericCueData::Start)
134         cue->setAlign(ASCIILiteral("start"), IGNORE_EXCEPTION);
135     else if (cueData->align() == GenericCueData::Middle)
136         cue->setAlign(ASCIILiteral("middle"), IGNORE_EXCEPTION);
137     else if (cueData->align() == GenericCueData::End)
138         cue->setAlign(ASCIILiteral("end"), IGNORE_EXCEPTION);
139     cue->setSnapToLines(false);
140
141     cue->didChange();
142 }
143
144 void InbandGenericTextTrack::addGenericCue(InbandTextTrackPrivate* trackPrivate, PassRefPtr<GenericCueData> prpCueData)
145 {
146     ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
147
148     RefPtr<GenericCueData> cueData = prpCueData;
149     if (m_cueMap.find(cueData.get()))
150         return;
151
152     RefPtr<TextTrackCueGeneric> cue = TextTrackCueGeneric::create(*scriptExecutionContext(), cueData->startTime(), cueData->endTime(), cueData->content());
153     updateCueFromCueData(cue.get(), cueData.get());
154     if (hasCue(cue.get(), TextTrackCue::IgnoreDuration)) {
155         LOG(Media, "InbandGenericTextTrack::addGenericCue ignoring already added cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
156         return;
157     }
158
159     if (cueData->status() != GenericCueData::Complete)
160         m_cueMap.add(cueData.get(), cue.get());
161
162     addCue(cue, ASSERT_NO_EXCEPTION);
163 }
164
165 void InbandGenericTextTrack::updateGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
166 {
167     RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
168     if (!cue)
169         return;
170
171     updateCueFromCueData(cue.get(), cueData);
172
173     if (cueData->status() == GenericCueData::Complete)
174         m_cueMap.remove(cueData);
175 }
176
177 void InbandGenericTextTrack::removeGenericCue(InbandTextTrackPrivate*, GenericCueData* cueData)
178 {
179     RefPtr<TextTrackCueGeneric> cue = m_cueMap.find(cueData);
180     if (cue) {
181         LOG(Media, "InbandGenericTextTrack::removeGenericCue removing cue: start=%.2f, end=%.2f, content=\"%s\"\n", cueData->startTime(), cueData->endTime(), cueData->content().utf8().data());
182         removeCue(cue.get(), IGNORE_EXCEPTION);
183     } else
184         m_cueMap.remove(cueData);
185 }
186
187 void InbandGenericTextTrack::removeCue(TextTrackCue* cue, ExceptionCode& ec)
188 {
189     m_cueMap.remove(cue);
190     TextTrack::removeCue(cue, ec);
191 }
192
193 } // namespace WebCore
194
195 #endif