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 blink {
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(FontWeight weight)55 FontWeight FontDescription::lighterWeight(FontWeight weight)
56 {
57 switch (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(FontWeight weight)77 FontWeight FontDescription::bolderWeight(FontWeight weight)
78 {
79 switch (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
largerSize(const Size & size)99 FontDescription::Size FontDescription::largerSize(const Size& size)
100 {
101 return Size(0, size.value * 1.2, size.isAbsolute);
102 }
103
smallerSize(const Size & size)104 FontDescription::Size FontDescription::smallerSize(const Size& size)
105 {
106 return Size(0, size.value / 1.2, size.isAbsolute);
107 }
108
traits() const109 FontTraits FontDescription::traits() const
110 {
111 return FontTraits(style(), variant(), weight(), stretch());
112 }
113
variantLigatures() const114 FontDescription::VariantLigatures FontDescription::variantLigatures() const
115 {
116 VariantLigatures ligatures;
117
118 ligatures.common = commonLigaturesState();
119 ligatures.discretionary = discretionaryLigaturesState();
120 ligatures.historical = historicalLigaturesState();
121 ligatures.contextual = contextualLigaturesState();
122
123 return ligatures;
124 }
125
setTraits(FontTraits traits)126 void FontDescription::setTraits(FontTraits traits)
127 {
128 setStyle(traits.style());
129 setVariant(traits.variant());
130 setWeight(traits.weight());
131 setStretch(traits.stretch());
132 }
133
setVariantLigatures(const VariantLigatures & ligatures)134 void FontDescription::setVariantLigatures(const VariantLigatures& ligatures)
135 {
136 m_commonLigaturesState = ligatures.common;
137 m_discretionaryLigaturesState = ligatures.discretionary;
138 m_historicalLigaturesState = ligatures.historical;
139 m_contextualLigaturesState = ligatures.contextual;
140
141 updateTypesettingFeatures();
142 }
143
effectiveFontSize() const144 float FontDescription::effectiveFontSize() const
145 {
146 float size = (RuntimeEnabledFeatures::subpixelFontScalingEnabled())
147 ? computedSize()
148 : computedPixelSize();
149
150 // Ensure that the effective precision matches the font-cache precision.
151 // This guarantees that the same precision is used regardless of cache status.
152 return floorf(size * FontCacheKey::precisionMultiplier()) / FontCacheKey::precisionMultiplier();
153 }
154
cacheKey(const FontFaceCreationParams & creationParams,FontTraits desiredTraits) const155 FontCacheKey FontDescription::cacheKey(const FontFaceCreationParams& creationParams, FontTraits desiredTraits) const
156 {
157 FontTraits fontTraits = desiredTraits.bitfield() ? desiredTraits : traits();
158
159 unsigned options =
160 static_cast<unsigned>(m_syntheticItalic) << 7 | // bit 8
161 static_cast<unsigned>(m_syntheticBold) << 6 | // bit 7
162 static_cast<unsigned>(m_fontSmoothing) << 4 | // bits 5-6
163 static_cast<unsigned>(m_textRendering) << 2 | // bits 3-4
164 static_cast<unsigned>(m_orientation) << 1 | // bit 2
165 static_cast<unsigned>(m_subpixelTextPosition); // bit 1
166
167 return FontCacheKey(creationParams, effectiveFontSize(), options | fontTraits.bitfield() << 8);
168 }
169
170
setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)171 void FontDescription::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)
172 {
173 s_defaultTypesettingFeatures = typesettingFeatures;
174 }
175
defaultTypesettingFeatures()176 TypesettingFeatures FontDescription::defaultTypesettingFeatures()
177 {
178 return s_defaultTypesettingFeatures;
179 }
180
updateTypesettingFeatures() const181 void FontDescription::updateTypesettingFeatures() const
182 {
183 m_typesettingFeatures = s_defaultTypesettingFeatures;
184
185 switch (textRendering()) {
186 case AutoTextRendering:
187 break;
188 case OptimizeSpeed:
189 m_typesettingFeatures &= ~(blink::Kerning | Ligatures);
190 break;
191 case GeometricPrecision:
192 case OptimizeLegibility:
193 m_typesettingFeatures |= blink::Kerning | Ligatures;
194 break;
195 }
196
197 switch (kerning()) {
198 case FontDescription::NoneKerning:
199 m_typesettingFeatures &= ~blink::Kerning;
200 break;
201 case FontDescription::NormalKerning:
202 m_typesettingFeatures |= blink::Kerning;
203 break;
204 case FontDescription::AutoKerning:
205 break;
206 }
207
208 // As per CSS (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property),
209 // When the effective letter-spacing between two characters is not zero (due to
210 // either justification or non-zero computed letter-spacing), user agents should
211 // not apply optional ligatures.
212 if (m_letterSpacing == 0) {
213 switch (commonLigaturesState()) {
214 case FontDescription::DisabledLigaturesState:
215 m_typesettingFeatures &= ~Ligatures;
216 break;
217 case FontDescription::EnabledLigaturesState:
218 m_typesettingFeatures |= Ligatures;
219 break;
220 case FontDescription::NormalLigaturesState:
221 break;
222 }
223
224 if (discretionaryLigaturesState() == FontDescription::EnabledLigaturesState
225 || historicalLigaturesState() == FontDescription::EnabledLigaturesState
226 || contextualLigaturesState() == FontDescription::EnabledLigaturesState) {
227 m_typesettingFeatures |= blink::Ligatures;
228 }
229 }
230 }
231
232 } // namespace blink
233