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 "core/platform/graphics/FloatRect.h" 28 #include "core/platform/graphics/FontBaseline.h" 29 #include "core/platform/graphics/FontData.h" 30 #include "core/platform/graphics/FontMetrics.h" 31 #include "core/platform/graphics/FontPlatformData.h" 32 #include "core/platform/graphics/GlyphBuffer.h" 33 #include "core/platform/graphics/GlyphMetricsMap.h" 34 #include "core/platform/graphics/GlyphPageTreeNode.h" 35 #if ENABLE(OPENTYPE_VERTICAL) 36 #include "core/platform/graphics/opentype/OpenTypeVerticalData.h" 37 #endif 38 #include "core/platform/graphics/TypesettingFeatures.h" 39 #include "wtf/OwnPtr.h" 40 #include "wtf/PassOwnPtr.h" 41 #include "wtf/text/StringHash.h" 42 #include "wtf/UnusedParam.h" 43 44 #if OS(DARWIN) 45 #include "wtf/RetainPtr.h" 46 #endif 47 48 namespace WebCore { 49 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 SimpleFontData : public FontData { 58 public: 59 class AdditionalFontData { 60 WTF_MAKE_FAST_ALLOCATED; 61 public: 62 virtual ~AdditionalFontData() { } 63 64 virtual void initializeFontData(SimpleFontData*, float fontSize) = 0; 65 virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0; 66 virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const = 0; 67 virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength) const = 0; 68 }; 69 70 // Used to create platform fonts. 71 static PassRefPtr<SimpleFontData> create(const FontPlatformData& platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false) 72 { 73 return adoptRef(new SimpleFontData(platformData, isCustomFont, isLoading, isTextOrientationFallback)); 74 } 75 76 // Used to create SVG Fonts. 77 static PassRefPtr<SimpleFontData> create(PassOwnPtr<AdditionalFontData> fontData, float fontSize, bool syntheticBold, bool syntheticItalic) 78 { 79 return adoptRef(new SimpleFontData(fontData, fontSize, syntheticBold, syntheticItalic)); 80 } 81 82 virtual ~SimpleFontData(); 83 84 static const SimpleFontData* systemFallback() { return reinterpret_cast<const SimpleFontData*>(-1); } 85 86 const FontPlatformData& platformData() const { return m_platformData; } 87 #if ENABLE(OPENTYPE_VERTICAL) 88 const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); } 89 #endif 90 91 PassRefPtr<SimpleFontData> smallCapsFontData(const FontDescription&) const; 92 PassRefPtr<SimpleFontData> emphasisMarkFontData(const FontDescription&) const; 93 PassRefPtr<SimpleFontData> brokenIdeographFontData() const; 94 95 PassRefPtr<SimpleFontData> variantFontData(const FontDescription& description, FontDataVariant variant) const 96 { 97 switch (variant) { 98 case SmallCapsVariant: 99 return smallCapsFontData(description); 100 case EmphasisMarkVariant: 101 return emphasisMarkFontData(description); 102 case BrokenIdeographVariant: 103 return brokenIdeographFontData(); 104 case AutoVariant: 105 case NormalVariant: 106 break; 107 } 108 ASSERT_NOT_REACHED(); 109 return const_cast<SimpleFontData*>(this); 110 } 111 112 PassRefPtr<SimpleFontData> verticalRightOrientationFontData() const; 113 PassRefPtr<SimpleFontData> uprightOrientationFontData() const; 114 115 bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; } 116 bool isTextOrientationFallback() const { return m_isTextOrientationFallback; } 117 118 FontMetrics& fontMetrics() { return m_fontMetrics; } 119 const FontMetrics& fontMetrics() const { return m_fontMetrics; } 120 float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); } 121 122 float maxCharWidth() const { return m_maxCharWidth; } 123 void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; } 124 125 float avgCharWidth() const { return m_avgCharWidth; } 126 void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; } 127 128 FloatRect boundsForGlyph(Glyph) const; 129 float widthForGlyph(Glyph glyph) const; 130 FloatRect platformBoundsForGlyph(Glyph) const; 131 float platformWidthForGlyph(Glyph) const; 132 133 float spaceWidth() const { return m_spaceWidth; } 134 float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; } 135 void setSpaceWidth(float spaceWidth) { m_spaceWidth = spaceWidth; } 136 137 #if OS(DARWIN) 138 float syntheticBoldOffset() const { return m_syntheticBoldOffset; } 139 #endif 140 141 Glyph spaceGlyph() const { return m_spaceGlyph; } 142 void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; } 143 Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; } 144 void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; } 145 bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; } 146 Glyph zeroGlyph() const { return m_zeroGlyph; } 147 void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; } 148 149 virtual const SimpleFontData* fontDataForCharacter(UChar32) const; 150 virtual bool containsCharacters(const UChar*, int length) const; 151 152 Glyph glyphForCharacter(UChar32) const; 153 154 void determinePitch(); 155 Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; } 156 157 AdditionalFontData* fontData() const { return m_fontData.get(); } 158 bool isSVGFont() const { return m_fontData; } 159 160 virtual bool isCustomFont() const { return m_isCustomFont; } 161 virtual bool isLoading() const { return m_isLoading; } 162 virtual bool isSegmented() const; 163 164 const GlyphData& missingGlyphData() const { return m_missingGlyphData; } 165 void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; } 166 167 #ifndef NDEBUG 168 virtual String description() const; 169 #endif 170 171 #if OS(DARWIN) 172 const SimpleFontData* getCompositeFontReferenceFontData(NSFont *key) const; 173 NSFont* getNSFont() const { return m_platformData.font(); } 174 #endif 175 176 #if OS(DARWIN) 177 CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const; 178 #endif 179 180 #if OS(DARWIN) || USE(HARFBUZZ) 181 bool canRenderCombiningCharacterSequence(const UChar*, size_t) const; 182 #endif 183 184 bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const 185 { 186 UNUSED_PARAM(glyphs); 187 UNUSED_PARAM(advances); 188 UNUSED_PARAM(glyphCount); 189 UNUSED_PARAM(typesettingFeatures); 190 return false; 191 } 192 193 private: 194 SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false); 195 196 SimpleFontData(PassOwnPtr<AdditionalFontData> , float fontSize, bool syntheticBold, bool syntheticItalic); 197 198 void platformInit(); 199 void platformGlyphInit(); 200 void platformCharWidthInit(); 201 void platformDestroy(); 202 203 void initCharWidths(); 204 205 PassRefPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const; 206 PassRefPtr<SimpleFontData> platformCreateScaledFontData(const FontDescription&, float scaleFactor) const; 207 208 FontMetrics m_fontMetrics; 209 float m_maxCharWidth; 210 float m_avgCharWidth; 211 212 FontPlatformData m_platformData; 213 OwnPtr<AdditionalFontData> m_fontData; 214 215 mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap; 216 mutable GlyphMetricsMap<float> m_glyphToWidthMap; 217 218 bool m_treatAsFixedPitch; 219 bool m_isCustomFont; // Whether or not we are custom font loaded via @font-face 220 bool m_isLoading; // Whether or not this custom font is still in the act of loading. 221 222 bool m_isTextOrientationFallback; 223 bool m_isBrokenIdeographFallback; 224 #if ENABLE(OPENTYPE_VERTICAL) 225 RefPtr<OpenTypeVerticalData> m_verticalData; 226 #endif 227 bool m_hasVerticalGlyphs; 228 229 Glyph m_spaceGlyph; 230 float m_spaceWidth; 231 Glyph m_zeroGlyph; 232 float m_adjustedSpaceWidth; 233 234 Glyph m_zeroWidthSpaceGlyph; 235 236 GlyphData m_missingGlyphData; 237 238 struct DerivedFontData { 239 static PassOwnPtr<DerivedFontData> create(bool forCustomFont); 240 ~DerivedFontData(); 241 242 bool forCustomFont; 243 RefPtr<SimpleFontData> smallCaps; 244 RefPtr<SimpleFontData> emphasisMark; 245 RefPtr<SimpleFontData> brokenIdeograph; 246 RefPtr<SimpleFontData> verticalRightOrientation; 247 RefPtr<SimpleFontData> uprightOrientation; 248 #if OS(DARWIN) 249 mutable RetainPtr<CFMutableDictionaryRef> compositeFontReferences; 250 #endif 251 252 private: 253 DerivedFontData(bool custom) 254 : forCustomFont(custom) 255 { 256 } 257 }; 258 259 mutable OwnPtr<DerivedFontData> m_derivedFontData; 260 261 #if OS(DARWIN) 262 float m_syntheticBoldOffset; 263 264 mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes; 265 #endif 266 267 #if OS(DARWIN) || USE(HARFBUZZ) 268 mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport; 269 #endif 270 }; 271 272 ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const 273 { 274 if (isZeroWidthSpaceGlyph(glyph)) 275 return FloatRect(); 276 277 FloatRect bounds; 278 if (m_glyphToBoundsMap) { 279 bounds = m_glyphToBoundsMap->metricsForGlyph(glyph); 280 if (bounds.width() != cGlyphSizeUnknown) 281 return bounds; 282 } 283 284 bounds = platformBoundsForGlyph(glyph); 285 if (!m_glyphToBoundsMap) 286 m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>); 287 m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds); 288 return bounds; 289 } 290 291 ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const 292 { 293 if (isZeroWidthSpaceGlyph(glyph)) 294 return 0; 295 296 float width = m_glyphToWidthMap.metricsForGlyph(glyph); 297 if (width != cGlyphSizeUnknown) 298 return width; 299 300 if (m_fontData) 301 width = m_fontData->widthForSVGGlyph(glyph, m_platformData.size()); 302 #if ENABLE(OPENTYPE_VERTICAL) 303 else if (m_verticalData) 304 #if OS(DARWIN) 305 width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset; 306 #else 307 width = m_verticalData->advanceHeight(this, glyph); 308 #endif 309 #endif 310 else 311 width = platformWidthForGlyph(glyph); 312 313 m_glyphToWidthMap.setMetricsForGlyph(glyph, width); 314 return width; 315 } 316 317 } // namespace WebCore 318 #endif // SimpleFontData_h 319