[Cocoa] Add SPI to disallow user-installed fonts
[WebKit-https.git] / Source / WebCore / platform / graphics / FontDescription.cpp
1 /*
2  * Copyright (C) 2007 Nicholas Shanks <contact@nickshanks.com>
3  * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "FontDescription.h"
32
33 #include "LocaleToScriptMapping.h"
34 #include <wtf/text/StringHash.h>
35
36 namespace WebCore {
37
38 struct SameSizeAsFontCascadeDescription {
39     Vector<void*> vector;
40 #if ENABLE(VARIATION_FONTS)
41     Vector<void*> vector2;
42 #else
43     char c;
44 #endif
45     AtomicString string;
46     int16_t fontSelectionRequest[3];
47     float size;
48     unsigned bitfields1;
49     unsigned bitfields2 : 22;
50     void* array;
51     float size2;
52     unsigned bitfields3 : 10;
53 };
54
55 COMPILE_ASSERT(sizeof(FontCascadeDescription) == sizeof(SameSizeAsFontCascadeDescription), FontCascadeDescription_should_stay_small);
56
57 FontDescription::FontDescription()
58     : m_fontSelectionRequest(FontCascadeDescription::initialWeight(), FontCascadeDescription::initialStretch(), FontCascadeDescription::initialItalic())
59     , m_orientation(Horizontal)
60     , m_nonCJKGlyphOrientation(static_cast<unsigned>(NonCJKGlyphOrientation::Mixed))
61     , m_widthVariant(RegularWidth)
62     , m_renderingMode(static_cast<unsigned>(FontRenderingMode::Normal))
63     , m_textRendering(AutoTextRendering)
64     , m_script(USCRIPT_COMMON)
65     , m_fontSynthesis(FontSynthesisWeight | FontSynthesisStyle | FontSynthesisSmallCaps)
66     , m_variantCommonLigatures(static_cast<unsigned>(FontVariantLigatures::Normal))
67     , m_variantDiscretionaryLigatures(static_cast<unsigned>(FontVariantLigatures::Normal))
68     , m_variantHistoricalLigatures(static_cast<unsigned>(FontVariantLigatures::Normal))
69     , m_variantContextualAlternates(static_cast<unsigned>(FontVariantLigatures::Normal))
70     , m_variantPosition(static_cast<unsigned>(FontVariantPosition::Normal))
71     , m_variantCaps(static_cast<unsigned>(FontVariantCaps::Normal))
72     , m_variantNumericFigure(static_cast<unsigned>(FontVariantNumericFigure::Normal))
73     , m_variantNumericSpacing(static_cast<unsigned>(FontVariantNumericSpacing::Normal))
74     , m_variantNumericFraction(static_cast<unsigned>(FontVariantNumericFraction::Normal))
75     , m_variantNumericOrdinal(static_cast<unsigned>(FontVariantNumericOrdinal::Normal))
76     , m_variantNumericSlashedZero(static_cast<unsigned>(FontVariantNumericSlashedZero::Normal))
77     , m_variantAlternates(static_cast<unsigned>(FontVariantAlternates::Normal))
78     , m_variantEastAsianVariant(static_cast<unsigned>(FontVariantEastAsianVariant::Normal))
79     , m_variantEastAsianWidth(static_cast<unsigned>(FontVariantEastAsianWidth::Normal))
80     , m_variantEastAsianRuby(static_cast<unsigned>(FontVariantEastAsianRuby::Normal))
81     , m_opticalSizing(static_cast<unsigned>(FontOpticalSizing::Enabled))
82     , m_fontStyleAxis(FontCascadeDescription::initialFontStyleAxis() == FontStyleAxis::ital)
83     , m_mayRepresentUserInstalledFont(true)
84 {
85 }
86
87 void FontDescription::setLocale(const AtomicString& locale)
88 {
89     m_locale = locale;
90     m_script = localeToScriptCodeForFontSelection(m_locale);
91 }
92
93 FontCascadeDescription::FontCascadeDescription()
94     : m_isAbsoluteSize(false)
95     , m_kerning(static_cast<unsigned>(Kerning::Auto))
96     , m_keywordSize(0)
97     , m_fontSmoothing(AutoSmoothing)
98     , m_isSpecifiedFont(false)
99 {
100 }
101
102 #if !USE_PLATFORM_SYSTEM_FALLBACK_LIST
103 void FontDescription::invalidateCaches()
104 {
105 }
106
107 unsigned FontCascadeDescription::effectiveFamilyCount() const
108 {
109     return familyCount();
110 }
111
112 FontFamilySpecification FontCascadeDescription::effectiveFamilyAt(unsigned i) const
113 {
114     return familyAt(i);
115 }
116 #endif
117
118 FontSelectionValue FontCascadeDescription::lighterWeight(FontSelectionValue weight)
119 {
120     if (weight < FontSelectionValue(100))
121         return weight;
122     if (weight < FontSelectionValue(550))
123         return FontSelectionValue(100);
124     if (weight < FontSelectionValue(750))
125         return FontSelectionValue(400);
126     return FontSelectionValue(700);
127 }
128
129 FontSelectionValue FontCascadeDescription::bolderWeight(FontSelectionValue weight)
130 {
131     if (weight < FontSelectionValue(350))
132         return FontSelectionValue(400);
133     if (weight < FontSelectionValue(550))
134         return FontSelectionValue(700);
135     if (weight < FontSelectionValue(900))
136         return FontSelectionValue(900);
137     return weight;
138 }
139
140 #if ENABLE(TEXT_AUTOSIZING)
141
142 bool FontCascadeDescription::familiesEqualForTextAutoSizing(const FontCascadeDescription& other) const
143 {
144     unsigned thisFamilyCount = familyCount();
145     unsigned otherFamilyCount = other.familyCount();
146
147     if (thisFamilyCount != otherFamilyCount)
148         return false;
149
150     for (unsigned i = 0; i < thisFamilyCount; ++i) {
151         if (!equalIgnoringASCIICase(familyAt(i), other.familyAt(i)))
152             return false;
153     }
154
155     return true;
156 }
157
158 #endif // ENABLE(TEXT_AUTOSIZING)
159
160 bool FontCascadeDescription::familyNamesAreEqual(const AtomicString& family1, const AtomicString& family2)
161 {
162     // FIXME: <rdar://problem/33594253> CoreText matches dot-prefixed font names case sensitively. We should
163     // always take the case insensitive patch once this radar is fixed.
164     if (family1.startsWith('.'))
165         return StringHash::equal(family1.string(), family2.string());
166     return ASCIICaseInsensitiveHash::equal(family1, family2);
167 }
168
169 unsigned FontCascadeDescription::familyNameHash(const AtomicString& family)
170 {
171     // FIXME: <rdar://problem/33594253> CoreText matches dot-prefixed font names case sensitively. We should
172     // always take the case insensitive patch once this radar is fixed.
173     if (family.startsWith('.'))
174         return StringHash::hash(family.string());
175     return ASCIICaseInsensitiveHash::hash(family);
176 }
177
178 String FontCascadeDescription::foldedFamilyName(const AtomicString& family)
179 {
180     // FIXME: <rdar://problem/33594253> CoreText matches dot-prefixed font names case sensitively. We should
181     // always take the case insensitive patch once this radar is fixed.
182     if (family.startsWith('.'))
183         return family.string();
184     return family.string().foldCase();
185 }
186
187 } // namespace WebCore