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 "core/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h"
     33 
     34 #include "SkPaint.h"
     35 #include "SkTypeface.h"
     36 #include "core/platform/NotImplemented.h"
     37 #include "core/platform/graphics/FontCache.h"
     38 #include "core/platform/graphics/harfbuzz/HarfBuzzFace.h"
     39 
     40 #include "public/platform/linux/WebFontInfo.h"
     41 #include "public/platform/linux/WebFontRenderStyle.h"
     42 #include "public/platform/linux/WebSandboxSupport.h"
     43 #include "public/platform/Platform.h"
     44 #include "wtf/text/StringImpl.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 static bool useSkiaSubpixelPositioning = false;
     55 
     56 void FontPlatformData::setHinting(SkPaint::Hinting hinting)
     57 {
     58     skiaHinting = hinting;
     59 }
     60 
     61 void FontPlatformData::setAutoHint(bool useAutoHint)
     62 {
     63     useSkiaAutoHint = useAutoHint;
     64 }
     65 
     66 void FontPlatformData::setUseBitmaps(bool useBitmaps)
     67 {
     68     useSkiaBitmaps = useBitmaps;
     69 }
     70 
     71 void FontPlatformData::setAntiAlias(bool useAntiAlias)
     72 {
     73     useSkiaAntiAlias = useAntiAlias;
     74 }
     75 
     76 void FontPlatformData::setSubpixelRendering(bool useSubpixelRendering)
     77 {
     78     useSkiaSubpixelRendering = useSubpixelRendering;
     79 }
     80 
     81 void FontPlatformData::setSubpixelPositioning(bool useSubpixelPositioning)
     82 {
     83     useSkiaSubpixelPositioning = useSubpixelPositioning;
     84 }
     85 
     86 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
     87     : m_textSize(0)
     88     , m_emSizeInFontUnits(0)
     89     , m_fakeBold(false)
     90     , m_fakeItalic(false)
     91     , m_orientation(Horizontal)
     92     , m_isHashTableDeletedValue(true)
     93 {
     94 }
     95 
     96 FontPlatformData::FontPlatformData()
     97     : m_textSize(0)
     98     , m_emSizeInFontUnits(0)
     99     , m_fakeBold(false)
    100     , m_fakeItalic(false)
    101     , m_orientation(Horizontal)
    102     , m_isHashTableDeletedValue(false)
    103 {
    104 }
    105 
    106 FontPlatformData::FontPlatformData(float textSize, bool fakeBold, bool fakeItalic)
    107     : m_textSize(textSize)
    108     , m_emSizeInFontUnits(0)
    109     , m_fakeBold(fakeBold)
    110     , m_fakeItalic(fakeItalic)
    111     , m_orientation(Horizontal)
    112     , m_isHashTableDeletedValue(false)
    113 {
    114 }
    115 
    116 FontPlatformData::FontPlatformData(const FontPlatformData& src)
    117     : m_typeface(src.m_typeface)
    118     , m_family(src.m_family)
    119     , m_textSize(src.m_textSize)
    120     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
    121     , m_fakeBold(src.m_fakeBold)
    122     , m_fakeItalic(src.m_fakeItalic)
    123     , m_orientation(src.m_orientation)
    124     , m_style(src.m_style)
    125     , m_harfBuzzFace(src.m_harfBuzzFace)
    126     , m_isHashTableDeletedValue(false)
    127 {
    128 }
    129 
    130 FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation)
    131     : m_typeface(tf)
    132     , m_family(family)
    133     , m_textSize(textSize)
    134     , m_emSizeInFontUnits(0)
    135     , m_fakeBold(fakeBold)
    136     , m_fakeItalic(fakeItalic)
    137     , m_orientation(orientation)
    138     , m_isHashTableDeletedValue(false)
    139 {
    140     querySystemForRenderStyle();
    141 }
    142 
    143 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    144     : m_typeface(src.m_typeface)
    145     , m_family(src.m_family)
    146     , m_textSize(textSize)
    147     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
    148     , m_fakeBold(src.m_fakeBold)
    149     , m_fakeItalic(src.m_fakeItalic)
    150     , m_orientation(src.m_orientation)
    151     , m_harfBuzzFace(src.m_harfBuzzFace)
    152     , m_isHashTableDeletedValue(false)
    153 {
    154     querySystemForRenderStyle();
    155 }
    156 
    157 FontPlatformData::~FontPlatformData()
    158 {
    159 }
    160 
    161 int FontPlatformData::emSizeInFontUnits() const
    162 {
    163     if (m_emSizeInFontUnits)
    164         return m_emSizeInFontUnits;
    165 
    166     m_emSizeInFontUnits = m_typeface->getUnitsPerEm();
    167     return m_emSizeInFontUnits;
    168 }
    169 
    170 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
    171 {
    172     m_typeface = src.m_typeface;
    173     m_family = src.m_family;
    174     m_textSize = src.m_textSize;
    175     m_fakeBold = src.m_fakeBold;
    176     m_fakeItalic = src.m_fakeItalic;
    177     m_harfBuzzFace = src.m_harfBuzzFace;
    178     m_orientation = src.m_orientation;
    179     m_style = src.m_style;
    180     m_emSizeInFontUnits = src.m_emSizeInFontUnits;
    181 
    182     return *this;
    183 }
    184 
    185 #ifndef NDEBUG
    186 String FontPlatformData::description() const
    187 {
    188     return String();
    189 }
    190 #endif
    191 
    192 void FontPlatformData::setupPaint(SkPaint* paint) const
    193 {
    194     paint->setAntiAlias(m_style.useAntiAlias);
    195     paint->setHinting(static_cast<SkPaint::Hinting>(m_style.hintStyle));
    196     paint->setEmbeddedBitmapText(m_style.useBitmaps);
    197     paint->setAutohinted(m_style.useAutoHint);
    198     paint->setSubpixelText(m_style.useSubpixelPositioning);
    199     if (m_style.useAntiAlias)
    200         paint->setLCDRenderText(m_style.useSubpixelRendering);
    201 
    202     const float ts = m_textSize >= 0 ? m_textSize : 12;
    203     paint->setTextSize(SkFloatToScalar(ts));
    204     paint->setTypeface(m_typeface.get());
    205     paint->setFakeBoldText(m_fakeBold);
    206     paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0);
    207 }
    208 
    209 SkFontID FontPlatformData::uniqueID() const
    210 {
    211     return m_typeface->uniqueID();
    212 }
    213 
    214 bool FontPlatformData::operator==(const FontPlatformData& a) const
    215 {
    216     // If either of the typeface pointers are null then we test for pointer
    217     // equality. Otherwise, we call SkTypeface::Equal on the valid pointers.
    218     bool typefacesEqual;
    219     if (!m_typeface || !a.m_typeface)
    220         typefacesEqual = m_typeface == a.m_typeface;
    221     else
    222         typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get());
    223 
    224     return typefacesEqual
    225         && m_textSize == a.m_textSize
    226         && m_fakeBold == a.m_fakeBold
    227         && m_fakeItalic == a.m_fakeItalic
    228         && m_orientation == a.m_orientation
    229         && m_style == a.m_style
    230         && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue;
    231 }
    232 
    233 unsigned FontPlatformData::hash() const
    234 {
    235     unsigned h = SkTypeface::UniqueID(m_typeface.get());
    236     h ^= 0x01010101 * ((static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
    237 
    238     // This memcpy is to avoid a reinterpret_cast that breaks strict-aliasing
    239     // rules. Memcpy is generally optimized enough so that performance doesn't
    240     // matter here.
    241     uint32_t textSizeBytes;
    242     memcpy(&textSizeBytes, &m_textSize, sizeof(uint32_t));
    243     h ^= textSizeBytes;
    244 
    245     return h;
    246 }
    247 
    248 bool FontPlatformData::isFixedPitch() const
    249 {
    250     notImplemented();
    251     return false;
    252 }
    253 
    254 HarfBuzzFace* FontPlatformData::harfBuzzFace() const
    255 {
    256     if (!m_harfBuzzFace)
    257         m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID());
    258 
    259     return m_harfBuzzFace.get();
    260 }
    261 
    262 void FontPlatformData::getRenderStyleForStrike(const char* font, int sizeAndStyle)
    263 {
    264     WebKit::WebFontRenderStyle style;
    265 
    266 #if OS(ANDROID)
    267     style.setDefaults();
    268 #else
    269     if (!font || !*font)
    270         style.setDefaults(); // It's probably a webfont. Take the system defaults.
    271     else if (WebKit::Platform::current()->sandboxSupport())
    272         WebKit::Platform::current()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
    273     else
    274         WebKit::WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
    275 #endif
    276 
    277     style.toFontRenderStyle(&m_style);
    278 }
    279 
    280 void FontPlatformData::querySystemForRenderStyle()
    281 {
    282     getRenderStyleForStrike(m_family.data(), (((int)m_textSize) << 2) | (m_typeface->style() & 3));
    283 
    284     // Fix FontRenderStyle::NoPreference to actual styles.
    285     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
    286          m_style.useAntiAlias = useSkiaAntiAlias;
    287 
    288     if (!m_style.useHinting)
    289         m_style.hintStyle = SkPaint::kNo_Hinting;
    290     else if (m_style.useHinting == FontRenderStyle::NoPreference)
    291         m_style.hintStyle = skiaHinting;
    292 
    293     if (m_style.useBitmaps == FontRenderStyle::NoPreference)
    294         m_style.useBitmaps = useSkiaBitmaps;
    295     if (m_style.useAutoHint == FontRenderStyle::NoPreference)
    296         m_style.useAutoHint = useSkiaAutoHint;
    297     if (m_style.useSubpixelPositioning == FontRenderStyle::NoPreference)
    298         m_style.useSubpixelPositioning = useSkiaSubpixelPositioning;
    299     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
    300         m_style.useAntiAlias = useSkiaAntiAlias;
    301     if (m_style.useSubpixelRendering == FontRenderStyle::NoPreference)
    302         m_style.useSubpixelRendering = useSkiaSubpixelRendering;
    303 }
    304 
    305 } // namespace WebCore
    306