1 /* 2 * Copyright 2009, The Android Open Source Project 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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 copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "FontCache.h" 29 30 #include "Font.h" 31 #include "FontPlatformData.h" 32 #include "NotImplemented.h" 33 #include "SimpleFontData.h" 34 #include "SkPaint.h" 35 #include "SkTypeface.h" 36 #include "SkUtils.h" 37 #include <wtf/text/CString.h> 38 39 namespace WebCore { 40 41 static const char* getFallbackFontName(const FontDescription& fontDescription) 42 { 43 switch (fontDescription.genericFamily()) { 44 case FontDescription::StandardFamily: 45 case FontDescription::SerifFamily: 46 return "serif"; 47 case FontDescription::SansSerifFamily: 48 return "sans-serif"; 49 case FontDescription::MonospaceFamily: 50 return "monospace"; 51 case FontDescription::CursiveFamily: 52 return "cursive"; 53 case FontDescription::FantasyFamily: 54 return "fantasy"; 55 case FontDescription::NoFamily: 56 default: 57 return ""; 58 } 59 } 60 61 static bool isFallbackFamily(String family) 62 { 63 return family.startsWith("-webkit-") 64 || equalIgnoringCase(family, "serif") 65 || equalIgnoringCase(family, "sans-serif") 66 || equalIgnoringCase(family, "sans") 67 || equalIgnoringCase(family, "monospace") 68 || equalIgnoringCase(family, "times") // skia aliases for serif 69 || equalIgnoringCase(family, "times new roman") 70 || equalIgnoringCase(family, "palatino") 71 || equalIgnoringCase(family, "georgia") 72 || equalIgnoringCase(family, "baskerville") 73 || equalIgnoringCase(family, "goudy") 74 || equalIgnoringCase(family, "cursive") 75 || equalIgnoringCase(family, "fantasy") 76 || equalIgnoringCase(family, "ITC Stone Serif") 77 || equalIgnoringCase(family, "arial") // skia aliases for sans-serif 78 || equalIgnoringCase(family, "helvetica") 79 || equalIgnoringCase(family, "tahoma") 80 || equalIgnoringCase(family, "verdana") 81 || equalIgnoringCase(family, "courier") // skia aliases for monospace 82 || equalIgnoringCase(family, "courier new") 83 || equalIgnoringCase(family, "monaco"); 84 } 85 86 static char* AtomicStringToUTF8String(const AtomicString& utf16) 87 { 88 SkASSERT(sizeof(uint16_t) == sizeof(utf16.characters()[0])); 89 const uint16_t* uni = (uint16_t*)utf16.characters(); 90 91 size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), 0); 92 char* utf8 = (char*)sk_malloc_throw(bytes + 1); 93 94 (void)SkUTF16_ToUTF8(uni, utf16.length(), utf8); 95 utf8[bytes] = 0; 96 return utf8; 97 } 98 99 100 void FontCache::platformInit() 101 { 102 } 103 104 const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) 105 { 106 // since all of our fonts logically map to the fallback, we can always claim 107 // that each font supports all characters. 108 return font.primaryFont(); 109 } 110 111 SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) 112 { 113 return 0; 114 } 115 116 SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description) 117 { 118 static const AtomicString sansStr("sans-serif"); 119 static const AtomicString serifStr("serif"); 120 static const AtomicString monospaceStr("monospace"); 121 122 FontPlatformData* fontPlatformData = 0; 123 switch (description.genericFamily()) { 124 case FontDescription::SerifFamily: 125 fontPlatformData = getCachedFontPlatformData(description, serifStr); 126 break; 127 case FontDescription::MonospaceFamily: 128 fontPlatformData = getCachedFontPlatformData(description, monospaceStr); 129 break; 130 case FontDescription::SansSerifFamily: 131 default: 132 fontPlatformData = getCachedFontPlatformData(description, sansStr); 133 break; 134 } 135 136 ASSERT(fontPlatformData); 137 return getCachedFontData(fontPlatformData); 138 } 139 140 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) 141 { 142 char* storage = 0; 143 const char* name = 0; 144 FontPlatformData* result = 0; 145 146 if (family.length()) { 147 storage = AtomicStringToUTF8String(family); 148 name = storage; 149 } else 150 name = getFallbackFontName(fontDescription); 151 152 int style = SkTypeface::kNormal; 153 if (fontDescription.weight() >= FontWeightBold) 154 style |= SkTypeface::kBold; 155 if (fontDescription.italic()) 156 style |= SkTypeface::kItalic; 157 158 // CreateFromName always returns a typeface, falling back to a default font 159 // if the one requested is not found. Calling Equal() with a null pointer 160 // serves to compare the returned font against the default, with the caveat 161 // that the default is always of normal style. If we detect the default, we 162 // ignore it and allow WebCore to give us the next font on the CSS fallback 163 // list. The only exception is if the family name is a commonly used generic 164 // family, as when called by getSimilarFontPlatformData() and 165 // getLastResortFallbackFont(). In this case, the default font is an 166 // acceptable result. 167 168 SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal); 169 170 if (!SkTypeface::Equal(tf, 0) || isFallbackFamily(family.string())) { 171 // We had to use normal styling to see if this was a default font. If 172 // we need bold or italic, replace with the corrected typeface. 173 if (style != SkTypeface::kNormal) { 174 tf->unref(); 175 tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style); 176 } 177 178 result = new FontPlatformData(tf, fontDescription.computedSize(), 179 (style & SkTypeface::kBold) && !tf->isBold(), 180 (style & SkTypeface::kItalic) && !tf->isItalic(), 181 fontDescription.orientation(), 182 fontDescription.textOrientation()); 183 } 184 185 tf->unref(); 186 sk_free(storage); 187 return result; 188 } 189 190 // new as of SVN change 36269, Sept 8, 2008 191 void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) 192 { 193 // Don't understand this yet, but it seems safe to leave unimplemented 194 } 195 196 } 197