Home | History | Annotate | Download | only in harfbuzz
      1 /*
      2  * Copyright (c) 2006, 2007, 2008, Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "platform/fonts/harfbuzz/FontPlatformDataHarfBuzz.h"
     33 
     34 #include "RuntimeEnabledFeatures.h"
     35 #include "SkTypeface.h"
     36 #include "platform/LayoutTestSupport.h"
     37 #include "platform/NotImplemented.h"
     38 #include "platform/fonts/FontCache.h"
     39 #include "platform/fonts/harfbuzz/HarfBuzzFace.h"
     40 
     41 #include "public/platform/linux/WebFontInfo.h"
     42 #include "public/platform/linux/WebFontRenderStyle.h"
     43 #include "public/platform/linux/WebSandboxSupport.h"
     44 #include "public/platform/Platform.h"
     45 #include "wtf/text/WTFString.h"
     46 
     47 namespace WebCore {
     48 
     49 static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
     50 static bool useSkiaAutoHint = true;
     51 static bool useSkiaBitmaps = true;
     52 static bool useSkiaAntiAlias = true;
     53 static bool useSkiaSubpixelRendering = false;
     54 
     55 void FontPlatformData::setHinting(SkPaint::Hinting hinting)
     56 {
     57     skiaHinting = hinting;
     58 }
     59 
     60 void FontPlatformData::setAutoHint(bool useAutoHint)
     61 {
     62     useSkiaAutoHint = useAutoHint;
     63 }
     64 
     65 void FontPlatformData::setUseBitmaps(bool useBitmaps)
     66 {
     67     useSkiaBitmaps = useBitmaps;
     68 }
     69 
     70 void FontPlatformData::setAntiAlias(bool useAntiAlias)
     71 {
     72     useSkiaAntiAlias = useAntiAlias;
     73 }
     74 
     75 void FontPlatformData::setSubpixelRendering(bool useSubpixelRendering)
     76 {
     77     useSkiaSubpixelRendering = useSubpixelRendering;
     78 }
     79 
     80 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
     81     : m_textSize(0)
     82     , m_emSizeInFontUnits(0)
     83     , m_fakeBold(false)
     84     , m_fakeItalic(false)
     85     , m_orientation(Horizontal)
     86     , m_isHashTableDeletedValue(true)
     87 {
     88 }
     89 
     90 FontPlatformData::FontPlatformData()
     91     : m_textSize(0)
     92     , m_emSizeInFontUnits(0)
     93     , m_fakeBold(false)
     94     , m_fakeItalic(false)
     95     , m_orientation(Horizontal)
     96     , m_isHashTableDeletedValue(false)
     97 {
     98 }
     99 
    100 FontPlatformData::FontPlatformData(float textSize, bool fakeBold, bool fakeItalic)
    101     : m_textSize(textSize)
    102     , m_emSizeInFontUnits(0)
    103     , m_fakeBold(fakeBold)
    104     , m_fakeItalic(fakeItalic)
    105     , m_orientation(Horizontal)
    106     , m_isHashTableDeletedValue(false)
    107 {
    108 }
    109 
    110 FontPlatformData::FontPlatformData(const FontPlatformData& src)
    111     : m_typeface(src.m_typeface)
    112     , m_family(src.m_family)
    113     , m_textSize(src.m_textSize)
    114     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
    115     , m_fakeBold(src.m_fakeBold)
    116     , m_fakeItalic(src.m_fakeItalic)
    117     , m_orientation(src.m_orientation)
    118     , m_style(src.m_style)
    119     , m_harfBuzzFace(0)
    120     , m_isHashTableDeletedValue(false)
    121 {
    122 }
    123 
    124 FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation, bool subpixelTextPosition)
    125     : m_typeface(tf)
    126     , m_family(family)
    127     , m_textSize(textSize)
    128     , m_emSizeInFontUnits(0)
    129     , m_fakeBold(fakeBold)
    130     , m_fakeItalic(fakeItalic)
    131     , m_orientation(orientation)
    132     , m_isHashTableDeletedValue(false)
    133 {
    134     querySystemForRenderStyle(subpixelTextPosition);
    135 }
    136 
    137 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    138     : m_typeface(src.m_typeface)
    139     , m_family(src.m_family)
    140     , m_textSize(textSize)
    141     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
    142     , m_fakeBold(src.m_fakeBold)
    143     , m_fakeItalic(src.m_fakeItalic)
    144     , m_orientation(src.m_orientation)
    145     , m_harfBuzzFace(0)
    146     , m_isHashTableDeletedValue(false)
    147 {
    148     querySystemForRenderStyle(FontDescription::subpixelPositioning());
    149 }
    150 
    151 FontPlatformData::~FontPlatformData()
    152 {
    153 }
    154 
    155 int FontPlatformData::emSizeInFontUnits() const
    156 {
    157     if (m_emSizeInFontUnits)
    158         return m_emSizeInFontUnits;
    159 
    160     m_emSizeInFontUnits = m_typeface->getUnitsPerEm();
    161     return m_emSizeInFontUnits;
    162 }
    163 
    164 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
    165 {
    166     m_typeface = src.m_typeface;
    167     m_family = src.m_family;
    168     m_textSize = src.m_textSize;
    169     m_fakeBold = src.m_fakeBold;
    170     m_fakeItalic = src.m_fakeItalic;
    171     m_harfBuzzFace = 0;
    172     m_orientation = src.m_orientation;
    173     m_style = src.m_style;
    174     m_emSizeInFontUnits = src.m_emSizeInFontUnits;
    175 
    176     return *this;
    177 }
    178 
    179 #ifndef NDEBUG
    180 String FontPlatformData::description() const
    181 {
    182     return String();
    183 }
    184 #endif
    185 
    186 void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext*) const
    187 {
    188     paint->setAntiAlias(m_style.useAntiAlias);
    189     paint->setHinting(static_cast<SkPaint::Hinting>(m_style.hintStyle));
    190     paint->setEmbeddedBitmapText(m_style.useBitmaps);
    191     paint->setAutohinted(m_style.useAutoHint);
    192     if (m_style.useAntiAlias)
    193         paint->setLCDRenderText(m_style.useSubpixelRendering);
    194 
    195     // TestRunner specifically toggles the subpixel positioning flag.
    196     if (RuntimeEnabledFeatures::subpixelFontScalingEnabled() && !isRunningLayoutTest())
    197         paint->setSubpixelText(true);
    198     else
    199         paint->setSubpixelText(m_style.useSubpixelPositioning);
    200 
    201     const float ts = m_textSize >= 0 ? m_textSize : 12;
    202     paint->setTextSize(SkFloatToScalar(ts));
    203     paint->setTypeface(m_typeface.get());
    204     paint->setFakeBoldText(m_fakeBold);
    205     paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0);
    206 }
    207 
    208 SkFontID FontPlatformData::uniqueID() const
    209 {
    210     return m_typeface->uniqueID();
    211 }
    212 
    213 String FontPlatformData::fontFamilyName() const
    214 {
    215     // FIXME(crbug.com/326582): come up with a proper way of handling SVG.
    216     if (!this->typeface())
    217         return "";
    218     SkTypeface::LocalizedStrings* fontFamilyIterator = this->typeface()->createFamilyNameIterator();
    219     SkTypeface::LocalizedString localizedString;
    220     while (fontFamilyIterator->next(&localizedString) && !localizedString.fString.size()) { }
    221     fontFamilyIterator->unref();
    222     return String(localizedString.fString.c_str());
    223 }
    224 
    225 bool FontPlatformData::operator==(const FontPlatformData& a) const
    226 {
    227     // If either of the typeface pointers are null then we test for pointer
    228     // equality. Otherwise, we call SkTypeface::Equal on the valid pointers.
    229     bool typefacesEqual;
    230     if (!m_typeface || !a.m_typeface)
    231         typefacesEqual = m_typeface == a.m_typeface;
    232     else
    233         typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get());
    234 
    235     return typefacesEqual
    236         && m_textSize == a.m_textSize
    237         && m_fakeBold == a.m_fakeBold
    238         && m_fakeItalic == a.m_fakeItalic
    239         && m_orientation == a.m_orientation
    240         && m_style == a.m_style
    241         && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue;
    242 }
    243 
    244 bool FontPlatformData::isFixedPitch() const
    245 {
    246     notImplemented();
    247     return false;
    248 }
    249 
    250 HarfBuzzFace* FontPlatformData::harfBuzzFace() const
    251 {
    252     if (!m_harfBuzzFace)
    253         m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID());
    254 
    255     return m_harfBuzzFace.get();
    256 }
    257 
    258 void FontPlatformData::getRenderStyleForStrike(const char* font, int sizeAndStyle)
    259 {
    260     blink::WebFontRenderStyle style;
    261 
    262 #if OS(ANDROID)
    263     style.setDefaults();
    264 #else
    265     if (!font || !*font)
    266         style.setDefaults(); // It's probably a webfont. Take the system defaults.
    267     else if (blink::Platform::current()->sandboxSupport())
    268         blink::Platform::current()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
    269     else
    270         blink::WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
    271 #endif
    272 
    273     style.toFontRenderStyle(&m_style);
    274 }
    275 
    276 void FontPlatformData::querySystemForRenderStyle(bool useSkiaSubpixelPositioning)
    277 {
    278     getRenderStyleForStrike(m_family.data(), (((int)m_textSize) << 2) | (m_typeface->style() & 3));
    279 
    280     // Fix FontRenderStyle::NoPreference to actual styles.
    281     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
    282          m_style.useAntiAlias = useSkiaAntiAlias;
    283 
    284     if (!m_style.useHinting)
    285         m_style.hintStyle = SkPaint::kNo_Hinting;
    286     else if (m_style.useHinting == FontRenderStyle::NoPreference)
    287         m_style.hintStyle = skiaHinting;
    288 
    289     if (m_style.useBitmaps == FontRenderStyle::NoPreference)
    290         m_style.useBitmaps = useSkiaBitmaps;
    291     if (m_style.useAutoHint == FontRenderStyle::NoPreference)
    292         m_style.useAutoHint = useSkiaAutoHint;
    293     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
    294         m_style.useAntiAlias = useSkiaAntiAlias;
    295     if (m_style.useSubpixelRendering == FontRenderStyle::NoPreference)
    296         m_style.useSubpixelRendering = useSkiaSubpixelRendering;
    297 
    298     // TestRunner specifically toggles the subpixel positioning flag.
    299     if (m_style.useSubpixelPositioning == FontRenderStyle::NoPreference
    300         || isRunningLayoutTest())
    301         m_style.useSubpixelPositioning = useSkiaSubpixelPositioning;
    302 }
    303 
    304 } // namespace WebCore
    305