1 /* 2 * Copyright (c) 2006, 2007, 2008, 2009 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 <unicode/locid.h> 33 #include "SkTypeface.h" 34 #include "core/platform/NotImplemented.h" 35 #include "core/platform/graphics/Font.h" 36 #include "core/platform/graphics/FontCache.h" 37 #include "core/platform/graphics/FontDescription.h" 38 #include "core/platform/graphics/SimpleFontData.h" 39 #include "wtf/Assertions.h" 40 #include "wtf/text/AtomicString.h" 41 #include "wtf/text/CString.h" 42 43 namespace WebCore { 44 45 void FontCache::platformInit() 46 { 47 } 48 49 #if !OS(WIN) && !OS(ANDROID) 50 PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacter(const Font& font, UChar32 c) 51 { 52 icu::Locale locale = icu::Locale::getDefault(); 53 FontCache::SimpleFontFamily family; 54 FontCache::getFontFamilyForCharacter(c, locale.getLanguage(), &family); 55 if (family.name.isEmpty()) 56 return 0; 57 58 AtomicString atomicFamily(family.name); 59 // Changes weight and/or italic of given FontDescription depends on 60 // the result of fontconfig so that keeping the correct font mapping 61 // of the given character. See http://crbug.com/32109 for details. 62 bool shouldSetFakeBold = false; 63 bool shouldSetFakeItalic = false; 64 FontDescription description(font.fontDescription()); 65 if (family.isBold && description.weight() < FontWeightBold) 66 description.setWeight(FontWeightBold); 67 if (!family.isBold && description.weight() >= FontWeightBold) { 68 shouldSetFakeBold = true; 69 description.setWeight(FontWeightNormal); 70 } 71 if (family.isItalic && description.italic() == FontItalicOff) 72 description.setItalic(FontItalicOn); 73 if (!family.isItalic && description.italic() == FontItalicOn) { 74 shouldSetFakeItalic = true; 75 description.setItalic(FontItalicOff); 76 } 77 78 FontPlatformData* substitutePlatformData = getFontResourcePlatformData(description, atomicFamily, DoNotRetain); 79 if (!substitutePlatformData) 80 return 0; 81 FontPlatformData platformData = FontPlatformData(*substitutePlatformData); 82 platformData.setFakeBold(shouldSetFakeBold); 83 platformData.setFakeItalic(shouldSetFakeItalic); 84 return getFontResourceData(&platformData, DoNotRetain); 85 } 86 87 #endif // !OS(WINDOWNS) && !OS(ANDROID) 88 89 PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font) 90 { 91 return 0; 92 } 93 94 PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain) 95 { 96 const FontPlatformData* fontPlatformData = getFallbackFontData(description); 97 if (!fontPlatformData) { 98 // we should at least have Arial; this is the SkFontHost_fontconfig last resort fallback 99 DEFINE_STATIC_LOCAL(const AtomicString, arialStr, ("Arial", AtomicString::ConstructFromLiteral)); 100 fontPlatformData = getFontResourcePlatformData(description, arialStr); 101 } 102 103 ASSERT(fontPlatformData); 104 return getFontResourceData(fontPlatformData, shouldRetain); 105 } 106 107 void FontCache::getTraitsInFamily(const AtomicString& familyName, 108 Vector<unsigned>& traitsMasks) 109 { 110 notImplemented(); 111 } 112 113 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, 114 const AtomicString& family) 115 { 116 const char* name = 0; 117 CString s; 118 119 // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into 120 // the fallback name (like "monospace") that fontconfig understands. 121 if (!family.length() || family.startsWith("-webkit-")) { 122 static const struct { 123 FontDescription::GenericFamilyType mType; 124 const char* mName; 125 } fontDescriptions[] = { 126 { FontDescription::SerifFamily, "serif" }, 127 { FontDescription::SansSerifFamily, "sans-serif" }, 128 { FontDescription::MonospaceFamily, "monospace" }, 129 { FontDescription::CursiveFamily, "cursive" }, 130 { FontDescription::FantasyFamily, "fantasy" } 131 }; 132 133 FontDescription::GenericFamilyType type = fontDescription.genericFamily(); 134 for (unsigned i = 0; i < SK_ARRAY_COUNT(fontDescriptions); i++) { 135 if (type == fontDescriptions[i].mType) { 136 name = fontDescriptions[i].mName; 137 break; 138 } 139 } 140 if (!name) 141 name = ""; 142 } else { 143 // convert the name to utf8 144 s = family.string().utf8(); 145 name = s.data(); 146 } 147 148 int style = SkTypeface::kNormal; 149 if (fontDescription.weight() >= FontWeightBold) 150 style |= SkTypeface::kBold; 151 if (fontDescription.italic()) 152 style |= SkTypeface::kItalic; 153 154 SkTypeface* tf = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style)); 155 if (!tf) 156 return 0; 157 158 FontPlatformData* result = 159 new FontPlatformData(tf, 160 name, 161 fontDescription.computedSize(), 162 (style & SkTypeface::kBold) && !tf->isBold(), 163 (style & SkTypeface::kItalic) && !tf->isItalic(), 164 fontDescription.orientation()); 165 tf->unref(); 166 return result; 167 } 168 169 } // namespace WebCore 170