Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / css / CSSFontFace.cpp
1 /*
2  * Copyright (C) 2007, 2008, 2011, 2013 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 "CSSFontFace.h"
28
29 #include "CSSFontFaceSource.h"
30 #include "CSSFontSelector.h"
31 #include "CSSSegmentedFontFace.h"
32 #include "Document.h"
33 #include "Font.h"
34 #include "FontDescription.h"
35 #include "FontLoader.h"
36 #include "RuntimeEnabledFeatures.h"
37
38 namespace WebCore {
39
40 bool CSSFontFace::isLoaded() const
41 {
42     size_t size = m_sources.size();
43     for (size_t i = 0; i < size; i++) {
44         if (!m_sources[i]->isLoaded())
45             return false;
46     }
47     return true;
48 }
49
50 bool CSSFontFace::isValid() const
51 {
52     size_t size = m_sources.size();
53     for (size_t i = 0; i < size; i++) {
54         if (m_sources[i]->isValid())
55             return true;
56     }
57     return false;
58 }
59
60 void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
61 {
62     m_segmentedFontFaces.add(segmentedFontFace);
63 }
64
65 void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
66 {
67     m_segmentedFontFaces.remove(segmentedFontFace);
68 }
69
70 void CSSFontFace::addSource(std::unique_ptr<CSSFontFaceSource> source)
71 {
72     source->setFontFace(this);
73     m_sources.append(WTFMove(source));
74 }
75
76 void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
77 {
78     if (source != m_activeSource)
79         return;
80
81     // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may
82     // require stopping in-progress font loading when the last
83     // CSSSegmentedFontFace is removed.
84     if (m_segmentedFontFaces.isEmpty())
85         return;
86
87     // Use one of the CSSSegmentedFontFaces' font selector. They all have
88     // the same font selector, so it's wasteful to store it in the CSSFontFace.
89     CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
90     fontSelector->fontLoaded();
91
92 #if ENABLE(FONT_LOAD_EVENTS)
93     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {
94         if (source->ensureFontData())
95             notifyFontLoader(Loaded);
96         else if (!isValid())
97             notifyFontLoader(Error);
98     }
99 #endif
100
101     for (auto* face : m_segmentedFontFaces)
102         face->fontLoaded(this);
103
104 #if ENABLE(FONT_LOAD_EVENTS)
105     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
106         notifyLoadingDone();
107 #endif
108 }
109
110 RefPtr<Font> CSSFontFace::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic)
111 {
112     m_activeSource = 0;
113     if (!isValid())
114         return 0;
115
116     ASSERT(!m_segmentedFontFaces.isEmpty());
117     CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
118
119 #if ENABLE(FONT_LOAD_EVENTS)
120     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == NotLoaded)
121         notifyFontLoader(Loading);
122 #endif
123
124     size_t size = m_sources.size();
125     for (size_t i = 0; i < size; ++i) {
126         if (RefPtr<Font> result = m_sources[i]->font(fontDescription, syntheticBold, syntheticItalic, fontSelector, m_featureSettings, m_variantSettings)) {
127             m_activeSource = m_sources[i].get();
128 #if ENABLE(FONT_LOAD_EVENTS)
129             if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading && m_sources[i]->isLoaded()) {
130                 notifyFontLoader(Loaded);
131                 notifyLoadingDone();
132             }
133 #endif
134             return result.release();
135         }
136     }
137
138 #if ENABLE(FONT_LOAD_EVENTS)
139     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {
140         notifyFontLoader(Error);
141         notifyLoadingDone();
142     }
143 #endif
144     return nullptr;
145 }
146
147 #if ENABLE(FONT_LOAD_EVENTS)
148 void CSSFontFace::notifyFontLoader(LoadState newState)
149 {
150     m_loadState = newState;
151
152     Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();
153     if (!document)
154         return;
155
156     switch (newState) {
157     case Loading:
158         document->fonts()->beginFontLoading(m_rule.get());
159         break;
160     case Loaded:
161         document->fonts()->fontLoaded(m_rule.get());
162         break;
163     case Error:
164         document->fonts()->loadError(m_rule.get(), m_activeSource);
165         break;
166     default:
167         break;
168     }
169 }
170
171 void CSSFontFace::notifyLoadingDone()
172 {
173     Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();
174     if (document)
175         document->fonts()->loadingDone();
176 }
177 #endif
178
179 #if ENABLE(SVG_FONTS)
180 bool CSSFontFace::hasSVGFontFaceSource() const
181 {
182     size_t size = m_sources.size();
183     for (size_t i = 0; i < size; i++) {
184         if (m_sources[i]->isSVGFontFaceSource())
185             return true;
186     }
187     return false;
188 }
189 #endif
190
191 }