2 * Copyright (C) 2007 Nicholas Shanks <contact@nickshanks.com>
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
31 #include "platform/fonts/FontDescription.h"
33 #include "platform/RuntimeEnabledFeatures.h"
34 #include "wtf/text/AtomicStringHash.h"
35 #include "wtf/text/StringHash.h"
39 struct SameSizeAsFontDescription
{
40 FontFamily familyList
;
41 RefPtr
<FontFeatureSettings
> m_featureSettings
;
44 // FXIME: Make them fit into one word.
46 uint32_t bitfields2
: 7;
49 static_assert(sizeof(FontDescription
) == sizeof(SameSizeAsFontDescription
), "FontDescription should stay small");
51 TypesettingFeatures
FontDescription::s_defaultTypesettingFeatures
= 0;
53 bool FontDescription::s_useSubpixelTextPositioning
= false;
55 FontWeight
FontDescription::lighterWeight(FontWeight weight
)
74 return FontWeightNormal
;
77 FontWeight
FontDescription::bolderWeight(FontWeight weight
)
96 return FontWeightNormal
;
99 FontDescription::Size
FontDescription::largerSize(const Size
& size
)
101 return Size(0, size
.value
* 1.2, size
.isAbsolute
);
104 FontDescription::Size
FontDescription::smallerSize(const Size
& size
)
106 return Size(0, size
.value
/ 1.2, size
.isAbsolute
);
109 FontTraits
FontDescription::traits() const
111 return FontTraits(style(), variant(), weight(), stretch());
114 FontDescription::VariantLigatures
FontDescription::variantLigatures() const
116 VariantLigatures ligatures
;
118 ligatures
.common
= commonLigaturesState();
119 ligatures
.discretionary
= discretionaryLigaturesState();
120 ligatures
.historical
= historicalLigaturesState();
121 ligatures
.contextual
= contextualLigaturesState();
126 static const AtomicString
& defaultLocale()
128 DEFINE_STATIC_LOCAL(AtomicString
, locale
, ());
130 locale
= AtomicString("en");
134 const AtomicString
& FontDescription::locale(bool includeDefault
) const
136 if (m_locale
.isNull() && includeDefault
)
137 return defaultLocale();
141 void FontDescription::setTraits(FontTraits traits
)
143 setStyle(traits
.style());
144 setVariant(traits
.variant());
145 setWeight(traits
.weight());
146 setStretch(traits
.stretch());
149 void FontDescription::setVariantLigatures(const VariantLigatures
& ligatures
)
151 m_commonLigaturesState
= ligatures
.common
;
152 m_discretionaryLigaturesState
= ligatures
.discretionary
;
153 m_historicalLigaturesState
= ligatures
.historical
;
154 m_contextualLigaturesState
= ligatures
.contextual
;
156 updateTypesettingFeatures();
159 float FontDescription::effectiveFontSize() const
161 // Ensure that the effective precision matches the font-cache precision.
162 // This guarantees that the same precision is used regardless of cache status.
163 float computedOrAdjustedSize
= hasSizeAdjust() ? adjustedSize() : computedSize();
164 return floorf(computedOrAdjustedSize
* FontCacheKey::precisionMultiplier()) / FontCacheKey::precisionMultiplier();
167 FontCacheKey
FontDescription::cacheKey(const FontFaceCreationParams
& creationParams
, FontTraits desiredTraits
) const
169 FontTraits fontTraits
= desiredTraits
.bitfield() ? desiredTraits
: traits();
172 static_cast<unsigned>(m_syntheticItalic
) << 6 | // bit 7
173 static_cast<unsigned>(m_syntheticBold
) << 5 | // bit 6
174 static_cast<unsigned>(m_textRendering
) << 3 | // bits 4-5
175 static_cast<unsigned>(m_orientation
) << 1 | // bit 2-3
176 static_cast<unsigned>(m_subpixelTextPosition
); // bit 1
178 return FontCacheKey(creationParams
, effectiveFontSize(), options
| fontTraits
.bitfield() << 7);
182 void FontDescription::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures
)
184 s_defaultTypesettingFeatures
= typesettingFeatures
;
187 TypesettingFeatures
FontDescription::defaultTypesettingFeatures()
189 return s_defaultTypesettingFeatures
;
192 void FontDescription::updateTypesettingFeatures() const
194 m_typesettingFeatures
= s_defaultTypesettingFeatures
;
196 switch (textRendering()) {
197 case AutoTextRendering
:
200 m_typesettingFeatures
&= ~(blink::Kerning
| Ligatures
);
202 case GeometricPrecision
:
203 case OptimizeLegibility
:
204 m_typesettingFeatures
|= blink::Kerning
| Ligatures
;
209 case FontDescription::NoneKerning
:
210 m_typesettingFeatures
&= ~blink::Kerning
;
212 case FontDescription::NormalKerning
:
213 m_typesettingFeatures
|= blink::Kerning
;
215 case FontDescription::AutoKerning
:
219 // As per CSS (http://dev.w3.org/csswg/css-text-3/#letter-spacing-property),
220 // When the effective letter-spacing between two characters is not zero (due to
221 // either justification or non-zero computed letter-spacing), user agents should
222 // not apply optional ligatures.
223 if (m_letterSpacing
== 0) {
224 switch (commonLigaturesState()) {
225 case FontDescription::DisabledLigaturesState
:
226 m_typesettingFeatures
&= ~Ligatures
;
228 case FontDescription::EnabledLigaturesState
:
229 m_typesettingFeatures
|= Ligatures
;
231 case FontDescription::NormalLigaturesState
:
235 if (discretionaryLigaturesState() == FontDescription::EnabledLigaturesState
236 || historicalLigaturesState() == FontDescription::EnabledLigaturesState
237 || contextualLigaturesState() == FontDescription::EnabledLigaturesState
) {
238 m_typesettingFeatures
|= blink::Ligatures
;