1 /* 2 * This file is part of the internal font implementation. 3 * 4 * Copyright (C) 2006, 2008, 2010 Apple Inc. All rights reserved. 5 * Copyright (C) 2007-2008 Torch Mobile, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 * 22 */ 23 24 #ifndef SimpleFontData_h 25 #define SimpleFontData_h 26 27 #include "platform/PlatformExport.h" 28 #include "platform/fonts/CustomFontData.h" 29 #include "platform/fonts/FontBaseline.h" 30 #include "platform/fonts/FontData.h" 31 #include "platform/fonts/FontMetrics.h" 32 #include "platform/fonts/FontPlatformData.h" 33 #include "platform/fonts/GlyphBuffer.h" 34 #include "platform/fonts/GlyphMetricsMap.h" 35 #include "platform/fonts/GlyphPageTreeNode.h" 36 #include "platform/fonts/TypesettingFeatures.h" 37 #include "platform/fonts/opentype/OpenTypeVerticalData.h" 38 #include "platform/geometry/FloatRect.h" 39 #include "wtf/OwnPtr.h" 40 #include "wtf/PassOwnPtr.h" 41 #include "wtf/text/StringHash.h" 42 43 #if OS(MACOSX) 44 #include "wtf/RetainPtr.h" 45 #endif 46 47 namespace WebCore { 48 49 class CSSFontFaceSource; 50 class FontDescription; 51 class SharedBuffer; 52 struct WidthIterator; 53 54 enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant }; 55 enum Pitch { UnknownPitch, FixedPitch, VariablePitch }; 56 57 class PLATFORM_EXPORT SimpleFontData : public FontData { 58 public: 59 // Used to create platform fonts. 60 static PassRefPtr<SimpleFontData> create(const FontPlatformData& platformData, PassRefPtr<CustomFontData> customData = 0, bool isTextOrientationFallback = false) 61 { 62 return adoptRef(new SimpleFontData(platformData, customData, isTextOrientationFallback)); 63 } 64 65 // Used to create SVG Fonts. 66 static PassRefPtr<SimpleFontData> create(PassRefPtr<CustomFontData> customData, float fontSize, bool syntheticBold, bool syntheticItalic) 67 { 68 return adoptRef(new SimpleFontData(customData, fontSize, syntheticBold, syntheticItalic)); 69 } 70 71 virtual ~SimpleFontData(); 72 73 static const SimpleFontData* systemFallback() { return reinterpret_cast<const SimpleFontData*>(-1); } 74 75 const FontPlatformData& platformData() const { return m_platformData; } 76 #if ENABLE(OPENTYPE_VERTICAL) 77 const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); } 78 #endif 79 80 PassRefPtr<SimpleFontData> smallCapsFontData(const FontDescription&) const; 81 PassRefPtr<SimpleFontData> emphasisMarkFontData(const FontDescription&) const; 82 PassRefPtr<SimpleFontData> brokenIdeographFontData() const; 83 84 PassRefPtr<SimpleFontData> variantFontData(const FontDescription& description, FontDataVariant variant) const 85 { 86 switch (variant) { 87 case SmallCapsVariant: 88 return smallCapsFontData(description); 89 case EmphasisMarkVariant: 90 return emphasisMarkFontData(description); 91 case BrokenIdeographVariant: 92 return brokenIdeographFontData(); 93 case AutoVariant: 94 case NormalVariant: 95 break; 96 } 97 ASSERT_NOT_REACHED(); 98 return const_cast<SimpleFontData*>(this); 99 } 100 101 PassRefPtr<SimpleFontData> verticalRightOrientationFontData() const; 102 PassRefPtr<SimpleFontData> uprightOrientationFontData() const; 103 104 bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; } 105 bool isTextOrientationFallback() const { return m_isTextOrientationFallback; } 106 107 FontMetrics& fontMetrics() { return m_fontMetrics; } 108 const FontMetrics& fontMetrics() const { return m_fontMetrics; } 109 float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); } 110 111 float maxCharWidth() const { return m_maxCharWidth; } 112 void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; } 113 114 float avgCharWidth() const { return m_avgCharWidth; } 115 void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; } 116 117 FloatRect boundsForGlyph(Glyph) const; 118 float widthForGlyph(Glyph glyph) const; 119 FloatRect platformBoundsForGlyph(Glyph) const; 120 float platformWidthForGlyph(Glyph) const; 121 122 float spaceWidth() const { return m_spaceWidth; } 123 float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; } 124 void setSpaceWidth(float spaceWidth) { m_spaceWidth = spaceWidth; } 125 126 #if OS(MACOSX) 127 float syntheticBoldOffset() const { return m_syntheticBoldOffset; } 128 #endif 129 130 Glyph spaceGlyph() const { return m_spaceGlyph; } 131 void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; } 132 Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; } 133 void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; } 134 bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; } 135 Glyph zeroGlyph() const { return m_zeroGlyph; } 136 void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; } 137 138 virtual const SimpleFontData* fontDataForCharacter(UChar32) const OVERRIDE; 139 virtual bool containsCharacters(const UChar*, int length) const OVERRIDE; 140 141 Glyph glyphForCharacter(UChar32) const; 142 143 void determinePitch(); 144 Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; } 145 146 bool isSVGFont() const { return m_customFontData && m_customFontData->isSVGFont(); } 147 virtual bool isCustomFont() const OVERRIDE { return m_customFontData; } 148 virtual bool isLoading() const OVERRIDE { return m_customFontData ? m_customFontData->isLoading() : false; } 149 virtual bool isLoadingFallback() const OVERRIDE { return m_customFontData ? m_customFontData->isLoadingFallback() : false; } 150 virtual bool isSegmented() const OVERRIDE; 151 152 const GlyphData& missingGlyphData() const { return m_missingGlyphData; } 153 void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; } 154 155 #ifndef NDEBUG 156 virtual String description() const; 157 #endif 158 159 #if OS(MACOSX) 160 const SimpleFontData* getCompositeFontReferenceFontData(NSFont *key) const; 161 NSFont* getNSFont() const { return m_platformData.font(); } 162 #endif 163 164 #if OS(MACOSX) 165 CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const; 166 #endif 167 168 #if OS(MACOSX) || USE(HARFBUZZ) 169 bool canRenderCombiningCharacterSequence(const UChar*, size_t) const; 170 #endif 171 172 bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t, TypesettingFeatures) const 173 { 174 return false; 175 } 176 177 PassRefPtr<CustomFontData> customFontData() const { return m_customFontData; } 178 179 private: 180 SimpleFontData(const FontPlatformData&, PassRefPtr<CustomFontData> customData, bool isTextOrientationFallback = false); 181 182 SimpleFontData(PassRefPtr<CustomFontData> customData, float fontSize, bool syntheticBold, bool syntheticItalic); 183 184 void platformInit(); 185 void platformGlyphInit(); 186 void platformCharWidthInit(); 187 void platformDestroy(); 188 189 void initCharWidths(); 190 191 PassRefPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const; 192 PassRefPtr<SimpleFontData> platformCreateScaledFontData(const FontDescription&, float scaleFactor) const; 193 194 FontMetrics m_fontMetrics; 195 float m_maxCharWidth; 196 float m_avgCharWidth; 197 198 FontPlatformData m_platformData; 199 200 mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap; 201 mutable GlyphMetricsMap<float> m_glyphToWidthMap; 202 203 bool m_treatAsFixedPitch; 204 205 bool m_isTextOrientationFallback; 206 bool m_isBrokenIdeographFallback; 207 #if ENABLE(OPENTYPE_VERTICAL) 208 RefPtr<OpenTypeVerticalData> m_verticalData; 209 #endif 210 bool m_hasVerticalGlyphs; 211 212 Glyph m_spaceGlyph; 213 float m_spaceWidth; 214 Glyph m_zeroGlyph; 215 float m_adjustedSpaceWidth; 216 217 Glyph m_zeroWidthSpaceGlyph; 218 219 GlyphData m_missingGlyphData; 220 221 struct DerivedFontData { 222 static PassOwnPtr<DerivedFontData> create(bool forCustomFont); 223 ~DerivedFontData(); 224 225 bool forCustomFont; 226 RefPtr<SimpleFontData> smallCaps; 227 RefPtr<SimpleFontData> emphasisMark; 228 RefPtr<SimpleFontData> brokenIdeograph; 229 RefPtr<SimpleFontData> verticalRightOrientation; 230 RefPtr<SimpleFontData> uprightOrientation; 231 #if OS(MACOSX) 232 mutable RetainPtr<CFMutableDictionaryRef> compositeFontReferences; 233 #endif 234 235 private: 236 DerivedFontData(bool custom) 237 : forCustomFont(custom) 238 { 239 } 240 }; 241 242 mutable OwnPtr<DerivedFontData> m_derivedFontData; 243 244 RefPtr<CustomFontData> m_customFontData; 245 246 #if OS(MACOSX) 247 float m_syntheticBoldOffset; 248 249 mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes; 250 #endif 251 252 #if OS(MACOSX) || USE(HARFBUZZ) 253 mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport; 254 #endif 255 }; 256 257 ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const 258 { 259 if (isZeroWidthSpaceGlyph(glyph)) 260 return FloatRect(); 261 262 FloatRect bounds; 263 if (m_glyphToBoundsMap) { 264 bounds = m_glyphToBoundsMap->metricsForGlyph(glyph); 265 if (bounds.width() != cGlyphSizeUnknown) 266 return bounds; 267 } 268 269 bounds = platformBoundsForGlyph(glyph); 270 if (!m_glyphToBoundsMap) 271 m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>); 272 m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds); 273 return bounds; 274 } 275 276 ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const 277 { 278 if (isZeroWidthSpaceGlyph(glyph)) 279 return 0; 280 281 float width = m_glyphToWidthMap.metricsForGlyph(glyph); 282 if (width != cGlyphSizeUnknown) 283 return width; 284 285 if (isSVGFont()) 286 width = m_customFontData->widthForSVGGlyph(glyph, m_platformData.size()); 287 #if ENABLE(OPENTYPE_VERTICAL) 288 else if (m_verticalData) 289 #if OS(MACOSX) 290 width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset; 291 #else 292 width = m_verticalData->advanceHeight(this, glyph); 293 #endif 294 #endif 295 else 296 width = platformWidthForGlyph(glyph); 297 298 m_glyphToWidthMap.setMetricsForGlyph(glyph, width); 299 return width; 300 } 301 302 } // namespace WebCore 303 #endif // SimpleFontData_h 304