Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / platform / graphics / FontRanges.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2015 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 "FontRanges.h"
28
29 #include "Font.h"
30 #include "FontSelector.h"
31 #include <wtf/Assertions.h>
32 #include <wtf/text/WTFString.h>
33
34 namespace WebCore {
35
36 const Font* FontRanges::Range::font(ExternalResourceDownloadPolicy policy) const
37 {
38     return m_fontAccessor->font(policy);
39 }
40
41 FontRanges::FontRanges() = default;
42
43 class TrivialFontAccessor final : public FontAccessor {
44 public:
45     static Ref<TrivialFontAccessor> create(Ref<Font>&& font)
46     {
47         return adoptRef(*new TrivialFontAccessor(WTFMove(font)));
48     }
49
50 private:
51     TrivialFontAccessor(RefPtr<Font>&& font)
52         : m_font(WTFMove(font))
53     {
54     }
55
56     const Font* font(ExternalResourceDownloadPolicy) const final
57     {
58         return m_font.get();
59     }
60
61     bool isLoading() const final
62     {
63         return m_font->isInterstitial();
64     }
65
66     RefPtr<Font> m_font;
67 };
68
69 FontRanges::FontRanges(RefPtr<Font>&& font)
70 {
71     if (font)
72         m_ranges.append(Range { 0, 0x7FFFFFFF, TrivialFontAccessor::create(font.releaseNonNull()) });
73 }
74
75 FontRanges::~FontRanges() = default;
76
77 GlyphData FontRanges::glyphDataForCharacter(UChar32 character, ExternalResourceDownloadPolicy policy) const
78 {
79     const Font* resultFont = nullptr;
80     for (auto& range : m_ranges) {
81         if (range.from() <= character && character <= range.to()) {
82             if (auto* font = range.font(policy)) {
83                 if (font->isInterstitial()) {
84                     policy = ExternalResourceDownloadPolicy::Forbid;
85                     if (!resultFont)
86                         resultFont = font;
87                 } else {
88                     auto glyphData = font->glyphDataForCharacter(character);
89                     if (glyphData.glyph) {
90                         auto* glyphDataFont = glyphData.font;
91                         if (glyphDataFont && glyphDataFont->visibility() == Font::Visibility::Visible && resultFont && resultFont->visibility() == Font::Visibility::Invisible)
92                             return GlyphData(glyphData.glyph, &glyphDataFont->invisibleFont());
93                         return glyphData;
94                     }
95                 }
96             }
97         }
98     }
99     if (resultFont) {
100         // We want higher-level code to be able to differentiate between
101         // "The interstitial font doesn't have the character" and
102         // "The real downloaded font doesn't have the character".
103         GlyphData result = resultFont->glyphDataForCharacter(character);
104         if (!result.font)
105             result.font = resultFont;
106         return result;
107     }
108     return GlyphData();
109 }
110
111 const Font* FontRanges::fontForCharacter(UChar32 character) const
112 {
113     return glyphDataForCharacter(character, ExternalResourceDownloadPolicy::Allow).font;
114 }
115
116 const Font& FontRanges::fontForFirstRange() const
117 {
118     auto* font = m_ranges[0].font(ExternalResourceDownloadPolicy::Forbid);
119     ASSERT(font);
120     return *font;
121 }
122
123 bool FontRanges::isLoading() const
124 {
125     for (auto& range : m_ranges) {
126         if (range.fontAccessor().isLoading())
127             return true;
128     }
129     return false;
130 }
131
132 } // namespace WebCore