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