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 "FontPlatformData.h" 33 34 #include "HarfbuzzSkia.h" 35 #include "NotImplemented.h" 36 #include "PlatformString.h" 37 #include "StringImpl.h" 38 39 #include "SkPaint.h" 40 #include "SkTypeface.h" 41 42 namespace WebCore { 43 44 static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting; 45 static bool isSkiaAntiAlias = true, isSkiaSubpixelGlyphs; 46 47 void FontPlatformData::setHinting(SkPaint::Hinting hinting) 48 { 49 skiaHinting = hinting; 50 } 51 52 void FontPlatformData::setAntiAlias(bool isAntiAlias) 53 { 54 isSkiaAntiAlias = isAntiAlias; 55 } 56 57 void FontPlatformData::setSubpixelGlyphs(bool isSubpixelGlyphs) 58 { 59 isSkiaSubpixelGlyphs = isSubpixelGlyphs; 60 } 61 62 FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() 63 { 64 HB_FreeFace(m_harfbuzzFace); 65 } 66 67 FontPlatformData::FontPlatformData(const FontPlatformData& src) 68 : m_typeface(src.m_typeface) 69 , m_textSize(src.m_textSize) 70 , m_fakeBold(src.m_fakeBold) 71 , m_fakeItalic(src.m_fakeItalic) 72 , m_harfbuzzFace(src.m_harfbuzzFace) 73 { 74 m_typeface->safeRef(); 75 } 76 77 FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic) 78 : m_typeface(tf) 79 , m_textSize(textSize) 80 , m_fakeBold(fakeBold) 81 , m_fakeItalic(fakeItalic) 82 { 83 m_typeface->safeRef(); 84 } 85 86 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) 87 : m_typeface(src.m_typeface) 88 , m_textSize(textSize) 89 , m_fakeBold(src.m_fakeBold) 90 , m_fakeItalic(src.m_fakeItalic) 91 , m_harfbuzzFace(src.m_harfbuzzFace) 92 { 93 m_typeface->safeRef(); 94 } 95 96 FontPlatformData::~FontPlatformData() 97 { 98 m_typeface->safeUnref(); 99 } 100 101 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) 102 { 103 SkRefCnt_SafeAssign(m_typeface, src.m_typeface); 104 105 m_textSize = src.m_textSize; 106 m_fakeBold = src.m_fakeBold; 107 m_fakeItalic = src.m_fakeItalic; 108 m_harfbuzzFace = src.m_harfbuzzFace; 109 110 return *this; 111 } 112 113 #ifndef NDEBUG 114 String FontPlatformData::description() const 115 { 116 return String(); 117 } 118 #endif 119 120 void FontPlatformData::setupPaint(SkPaint* paint) const 121 { 122 const float ts = m_textSize > 0 ? m_textSize : 12; 123 124 paint->setAntiAlias(isSkiaAntiAlias); 125 paint->setHinting(skiaHinting); 126 paint->setLCDRenderText(isSkiaSubpixelGlyphs); 127 paint->setTextSize(SkFloatToScalar(ts)); 128 paint->setTypeface(m_typeface); 129 paint->setFakeBoldText(m_fakeBold); 130 paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0); 131 } 132 133 SkFontID FontPlatformData::uniqueID() const 134 { 135 return m_typeface->uniqueID(); 136 } 137 138 bool FontPlatformData::operator==(const FontPlatformData& a) const 139 { 140 // If either of the typeface pointers are invalid (either NULL or the 141 // special deleted value) then we test for pointer equality. Otherwise, we 142 // call SkTypeface::Equal on the valid pointers. 143 bool typefacesEqual; 144 if (m_typeface == hashTableDeletedFontValue() 145 || a.m_typeface == hashTableDeletedFontValue() 146 || !m_typeface 147 || !a.m_typeface) 148 typefacesEqual = m_typeface == a.m_typeface; 149 else 150 typefacesEqual = SkTypeface::Equal(m_typeface, a.m_typeface); 151 152 return typefacesEqual 153 && m_textSize == a.m_textSize 154 && m_fakeBold == a.m_fakeBold 155 && m_fakeItalic == a.m_fakeItalic; 156 } 157 158 unsigned FontPlatformData::hash() const 159 { 160 unsigned h = SkTypeface::UniqueID(m_typeface); 161 h ^= 0x01010101 * ((static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic)); 162 163 // This memcpy is to avoid a reinterpret_cast that breaks strict-aliasing 164 // rules. Memcpy is generally optimized enough so that performance doesn't 165 // matter here. 166 uint32_t textSizeBytes; 167 memcpy(&textSizeBytes, &m_textSize, sizeof(uint32_t)); 168 h ^= textSizeBytes; 169 170 return h; 171 } 172 173 bool FontPlatformData::isFixedPitch() const 174 { 175 notImplemented(); 176 return false; 177 } 178 179 HB_FaceRec_* FontPlatformData::harfbuzzFace() const 180 { 181 if (!m_harfbuzzFace) 182 m_harfbuzzFace = RefCountedHarfbuzzFace::create(HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable)); 183 184 return m_harfbuzzFace->face(); 185 } 186 187 } // namespace WebCore 188