Home | History | Annotate | Download | only in fonts
      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