1 /*
2 * Copyright (C) 2007 Nicholas Shanks <contact@nickshanks.com>
3 * Copyright (C) 2008 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 Computer, 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 "platform/fonts/FontDescription.h"
32
33 #include "platform/RuntimeEnabledFeatures.h"
34 #include "wtf/text/AtomicStringHash.h"
35 #include "wtf/text/StringHash.h"
36
37 namespace WebCore {
38
39 struct SameSizeAsFontDescription {
40 FontFamily familyList;
41 RefPtr<FontFeatureSettings> m_featureSettings;
42 String locale;
43 float sizes[4];
44 // FXIME: Make them fit into one word.
45 uint32_t bitfields;
46 uint32_t bitfields2 : 7;
47 };
48
49 COMPILE_ASSERT(sizeof(FontDescription) == sizeof(SameSizeAsFontDescription), FontDescription_should_stay_small);
50
51 TypesettingFeatures FontDescription::s_defaultTypesettingFeatures = 0;
52
53 bool FontDescription::s_useSubpixelTextPositioning = false;
54
lighterWeight(void) const55 FontWeight FontDescription::lighterWeight(void) const
56 {
57 switch (m_weight) {
58 case FontWeight100:
59 case FontWeight200:
60 case FontWeight300:
61 case FontWeight400:
62 case FontWeight500:
63 return FontWeight100;
64
65 case FontWeight600:
66 case FontWeight700:
67 return FontWeight400;
68
69 case FontWeight800:
70 case FontWeight900:
71 return FontWeight700;
72 }
73 ASSERT_NOT_REACHED();
74 return FontWeightNormal;
75 }
76
bolderWeight(void) const77 FontWeight FontDescription::bolderWeight(void) const
78 {
79 switch (m_weight) {
80 case FontWeight100:
81 case FontWeight200:
82 case FontWeight300:
83 return FontWeight400;
84
85 case FontWeight400:
86 case FontWeight500:
87 return FontWeight700;
88
89 case FontWeight600:
90 case FontWeight700:
91 case FontWeight800:
92 case FontWeight900:
93 return FontWeight900;
94 }
95 ASSERT_NOT_REACHED();
96 return FontWeightNormal;
97 }
98
traits() const99 FontTraits FontDescription::traits() const
100 {
101 return FontTraits(style(), variant(), weight(), stretch());
102 }
103
setTraits(FontTraits traits)104 void FontDescription::setTraits(FontTraits traits)
105 {
106 setStyle(traits.style());
107 setVariant(traits.variant());
108 setWeight(traits.weight());
109 setStretch(traits.stretch());
110 }
111
makeNormalFeatureSettings() const112 FontDescription FontDescription::makeNormalFeatureSettings() const
113 {
114 FontDescription normalDescription(*this);
115 normalDescription.setFeatureSettings(nullptr);
116 return normalDescription;
117 }
118
effectiveFontSize() const119 float FontDescription::effectiveFontSize() const
120 {
121 float size = (RuntimeEnabledFeatures::subpixelFontScalingEnabled())
122 ? computedSize()
123 : computedPixelSize();
124
125 // Ensure that the effective precision matches the font-cache precision.
126 // This guarantees that the same precision is used regardless of cache status.
127 return floorf(size * FontCacheKey::precisionMultiplier()) / FontCacheKey::precisionMultiplier();
128 }
129
cacheKey(const AtomicString & familyName,FontTraits desiredTraits) const130 FontCacheKey FontDescription::cacheKey(const AtomicString& familyName, FontTraits desiredTraits) const
131 {
132 FontTraits fontTraits = desiredTraits.mask()
133 ? desiredTraits
134 : traits();
135
136 unsigned options =
137 static_cast<unsigned>(m_syntheticItalic) << 7 | // bit 8
138 static_cast<unsigned>(m_syntheticBold) << 6 | // bit 7
139 static_cast<unsigned>(m_fontSmoothing) << 4 | // bits 5-6
140 static_cast<unsigned>(m_textRendering) << 2 | // bits 3-4
141 static_cast<unsigned>(m_orientation) << 1 | // bit 2
142 static_cast<unsigned>(m_subpixelTextPosition); // bit 1
143
144 return FontCacheKey(familyName, effectiveFontSize(), options | fontTraits.mask() << 8);
145 }
146
147
setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)148 void FontDescription::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)
149 {
150 s_defaultTypesettingFeatures = typesettingFeatures;
151 }
152
defaultTypesettingFeatures()153 TypesettingFeatures FontDescription::defaultTypesettingFeatures()
154 {
155 return s_defaultTypesettingFeatures;
156 }
157
updateTypesettingFeatures() const158 void FontDescription::updateTypesettingFeatures() const
159 {
160 m_typesettingFeatures = s_defaultTypesettingFeatures;
161
162 switch (textRendering()) {
163 case AutoTextRendering:
164 break;
165 case OptimizeSpeed:
166 m_typesettingFeatures &= ~(WebCore::Kerning | Ligatures);
167 break;
168 case GeometricPrecision:
169 case OptimizeLegibility:
170 m_typesettingFeatures |= WebCore::Kerning | Ligatures;
171 break;
172 }
173
174 switch (kerning()) {
175 case FontDescription::NoneKerning:
176 m_typesettingFeatures &= ~WebCore::Kerning;
177 break;
178 case FontDescription::NormalKerning:
179 m_typesettingFeatures |= WebCore::Kerning;
180 break;
181 case FontDescription::AutoKerning:
182 break;
183 }
184
185 // As per CSS (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property),
186 // When the effective letter-spacing between two characters is not zero (due to
187 // either justification or non-zero computed letter-spacing), user agents should
188 // not apply optional ligatures.
189 if (m_letterSpacing == 0) {
190 switch (commonLigaturesState()) {
191 case FontDescription::DisabledLigaturesState:
192 m_typesettingFeatures &= ~Ligatures;
193 break;
194 case FontDescription::EnabledLigaturesState:
195 m_typesettingFeatures |= Ligatures;
196 break;
197 case FontDescription::NormalLigaturesState:
198 break;
199 }
200
201 if (discretionaryLigaturesState() == FontDescription::EnabledLigaturesState
202 || historicalLigaturesState() == FontDescription::EnabledLigaturesState
203 || contextualLigaturesState() == FontDescription::EnabledLigaturesState) {
204 m_typesettingFeatures |= WebCore::Ligatures;
205 }
206 }
207 }
208
209 } // namespace WebCore
210