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