1 /* 2 * Copyright (C) 2007 Nicholas Shanks <contact (at) 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 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 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 99 FontDescription::Size FontDescription::largerSize(const Size& size) 100 { 101 return Size(0, size.value * 1.2, size.isAbsolute); 102 } 103 104 FontDescription::Size FontDescription::smallerSize(const Size& size) 105 { 106 return Size(0, size.value / 1.2, size.isAbsolute); 107 } 108 109 FontTraits FontDescription::traits() const 110 { 111 return FontTraits(style(), variant(), weight(), stretch()); 112 } 113 114 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 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 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 144 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 155 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 171 void FontDescription::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures) 172 { 173 s_defaultTypesettingFeatures = typesettingFeatures; 174 } 175 176 TypesettingFeatures FontDescription::defaultTypesettingFeatures() 177 { 178 return s_defaultTypesettingFeatures; 179 } 180 181 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