1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "core/css/FontLoader.h"
7
8#include "core/css/CSSFontSelector.h"
9#include "core/fetch/FontResource.h"
10#include "core/fetch/ResourceFetcher.h"
11
12namespace blink {
13
14FontLoader::FontLoader(CSSFontSelector* fontSelector, ResourceFetcher* resourceFetcher)
15    : m_beginLoadingTimer(this, &FontLoader::beginLoadTimerFired)
16    , m_fontSelector(fontSelector)
17    , m_resourceFetcher(resourceFetcher)
18{
19}
20
21FontLoader::~FontLoader()
22{
23#if ENABLE(OILPAN)
24    if (!m_resourceFetcher) {
25        ASSERT(m_fontsToBeginLoading.isEmpty());
26        return;
27    }
28    m_beginLoadingTimer.stop();
29    // This will decrement the request counts on the ResourceFetcher for all the
30    // fonts that were pending at the time the FontLoader dies.
31    clearPendingFonts();
32#endif
33}
34
35void FontLoader::addFontToBeginLoading(FontResource* fontResource)
36{
37    if (!m_resourceFetcher || !fontResource->stillNeedsLoad() || fontResource->loadScheduled())
38        return;
39
40    m_fontsToBeginLoading.append(
41        std::make_pair(fontResource, ResourceLoader::RequestCountTracker(m_resourceFetcher, fontResource)));
42    fontResource->didScheduleLoad();
43    if (!m_beginLoadingTimer.isActive())
44        m_beginLoadingTimer.startOneShot(0, FROM_HERE);
45}
46
47void FontLoader::beginLoadTimerFired(Timer<blink::FontLoader>*)
48{
49    loadPendingFonts();
50}
51
52void FontLoader::loadPendingFonts()
53{
54    ASSERT(m_resourceFetcher);
55
56    FontsToLoadVector fontsToBeginLoading;
57    fontsToBeginLoading.swap(m_fontsToBeginLoading);
58    for (FontsToLoadVector::iterator it = fontsToBeginLoading.begin(); it != fontsToBeginLoading.end(); ++it) {
59        FontResource* fontResource = it->first.get();
60        fontResource->beginLoadIfNeeded(m_resourceFetcher);
61    }
62
63    // When the local fontsToBeginLoading vector goes out of scope it will
64    // decrement the request counts on the ResourceFetcher for all the fonts
65    // that were just loaded.
66}
67
68void FontLoader::fontFaceInvalidated()
69{
70    if (m_fontSelector)
71        m_fontSelector->fontFaceInvalidated();
72}
73
74#if !ENABLE(OILPAN)
75void FontLoader::clearResourceFetcherAndFontSelector()
76{
77    if (!m_resourceFetcher) {
78        ASSERT(m_fontsToBeginLoading.isEmpty());
79        return;
80    }
81
82    m_beginLoadingTimer.stop();
83    clearPendingFonts();
84    m_resourceFetcher = nullptr;
85    m_fontSelector = nullptr;
86}
87#endif
88
89void FontLoader::clearPendingFonts()
90{
91    for (FontsToLoadVector::iterator it = m_fontsToBeginLoading.begin(); it != m_fontsToBeginLoading.end(); ++it)
92        it->first->didUnscheduleLoad();
93    m_fontsToBeginLoading.clear();
94}
95
96void FontLoader::trace(Visitor* visitor)
97{
98    visitor->trace(m_resourceFetcher);
99    visitor->trace(m_fontSelector);
100}
101
102} // namespace blink
103