18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2009, The Android Open Source Project 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 8e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * * Redistributions of source code must retain the above copyright 9e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * notice, this list of conditions and the following disclaimer. 10e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * * Redistributions in binary form must reproduce the above copyright 11e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * notice, this list of conditions and the following disclaimer in the 12e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 14e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 15e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24e03118fd5d9b776df29de3f96232ed6b5395c845Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontCache.h" 29775c244a94159b3e986a8691f1a5f092f50af9d0Russell Brenner 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Font.h" 31775c244a94159b3e986a8691f1a5f092f50af9d0Russell Brenner#include "FontPlatformData.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NotImplemented.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SimpleFontData.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkPaint.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkTypeface.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkUtils.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 40cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic const char* getFallbackFontName(const FontDescription& fontDescription) 41cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{ 42cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner switch (fontDescription.genericFamily()) { 43cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::StandardFamily: 44cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::SerifFamily: 45cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return "serif"; 46cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::SansSerifFamily: 47cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return "sans-serif"; 48cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::MonospaceFamily: 49cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return "monospace"; 50cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::CursiveFamily: 51cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return "cursive"; 52cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::FantasyFamily: 53cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return "fantasy"; 54cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::NoFamily: 55cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner default: 56cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return ""; 57cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner } 58cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner} 59cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 60cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic bool isFallbackFamily(String family) 61cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{ 62cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return family.startsWith("-webkit-") 63cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner || equalIgnoringCase(family, "serif") 64cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner || equalIgnoringCase(family, "sans-serif") 65cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner || equalIgnoringCase(family, "sans") 66cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner || equalIgnoringCase(family, "monospace") 67e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "times") // skia aliases for serif 68e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "times new roman") 69e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "palatino") 70e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "georgia") 71e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "baskerville") 72e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "goudy") 73cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner || equalIgnoringCase(family, "cursive") 74e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "fantasy") 75e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "ITC Stone Serif") 76e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "arial") // skia aliases for sans-serif 77e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "helvetica") 78e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "tahoma") 79e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "verdana") 80e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "courier") // skia aliases for monospace 81e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "courier new") 82e34da8b408683ed4f0b8859ce243fb89dd9ccf83Russell Brenner || equalIgnoringCase(family, "monaco"); 83cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner} 84cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 85cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic char* AtomicStringToUTF8String(const AtomicString& utf16) 86cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{ 87cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner SkASSERT(sizeof(uint16_t) == sizeof(utf16.characters()[0])); 88cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner const uint16_t* uni = (uint16_t*)utf16.characters(); 89cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 90cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), 0); 91cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner char* utf8 = (char*)sk_malloc_throw(bytes + 1); 92cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 93cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner (void)SkUTF16_ToUTF8(uni, utf16.length(), utf8); 94cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner utf8[bytes] = 0; 95cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return utf8; 96cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner} 97cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 98cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::platformInit() 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // since all of our fonts logically map to the fallback, we can always claim 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that each font supports all characters. 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return font.primaryFont(); 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 110477d5d728b7ab5d2a4fbefc981a5b5d41e15f187Steve BlockSimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 115cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell BrennerSimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description) 1167f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner{ 117cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner static const AtomicString sansStr("sans-serif"); 118cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner static const AtomicString serifStr("serif"); 119cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner static const AtomicString monospaceStr("monospace"); 120cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 121cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner FontPlatformData* fontPlatformData = 0; 122cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner switch (description.genericFamily()) { 123cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::SerifFamily: 124cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner fontPlatformData = getCachedFontPlatformData(description, serifStr); 125cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner break; 126cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::MonospaceFamily: 127cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner fontPlatformData = getCachedFontPlatformData(description, monospaceStr); 128cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner break; 129cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner case FontDescription::SansSerifFamily: 130cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner default: 131cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner fontPlatformData = getCachedFontPlatformData(description, sansStr); 132cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner break; 133cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner } 1347f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner 135cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner ASSERT(fontPlatformData); 136cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner return getCachedFontData(fontPlatformData); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 141cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner char* storage = 0; 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const char* name = 0; 143cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner FontPlatformData* result = 0; 1447f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner 145cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner if (family.length()) { 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project storage = AtomicStringToUTF8String(family); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project name = storage; 148cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner } else 149cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner name = getFallbackFontName(fontDescription); 1507f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int style = SkTypeface::kNormal; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fontDescription.weight() >= FontWeightBold) 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style |= SkTypeface::kBold; 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fontDescription.italic()) 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project style |= SkTypeface::kItalic; 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 157cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // CreateFromName always returns a typeface, falling back to a default font 158cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // if the one requested is not found. Calling Equal() with a null pointer 159cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // serves to compare the returned font against the default, with the caveat 160cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // that the default is always of normal style. If we detect the default, we 161cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // ignore it and allow WebCore to give us the next font on the CSS fallback 162cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // list. The only exception is if the family name is a commonly used generic 163cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // family, as when called by getSimilarFontPlatformData() and 164cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // getLastResortFallbackFont(). In this case, the default font is an 165cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // acceptable result. 166cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 167cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal); 168cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 169cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner if (!SkTypeface::Equal(tf, 0) || isFallbackFamily(family.string())) { 170cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // We had to use normal styling to see if this was a default font. If 171cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner // we need bold or italic, replace with the corrected typeface. 172cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner if (style != SkTypeface::kNormal) { 173cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner tf->unref(); 174cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style); 175cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner } 176cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner 177cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner result = new FontPlatformData(tf, fontDescription.computedSize(), 1782622fb80bac785bc80c698cc7397e160b95db1e7Victoria Lease (style & SkTypeface::kBold), 179295fd960c28a38cfa7a28d4b8f68f474394f7fb0claireho (style & SkTypeface::kItalic) && !tf->isItalic(), 180295fd960c28a38cfa7a28d4b8f68f474394f7fb0claireho fontDescription.orientation(), 181295fd960c28a38cfa7a28d4b8f68f474394f7fb0claireho fontDescription.textOrientation()); 182cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner } 183fd0bf63b4addb1bcb90de078bbd4700e2545a69fRussell Brenner 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tf->unref(); 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sk_free(storage); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // new as of SVN change 36269, Sept 8, 2008 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't understand this yet, but it seems safe to leave unimplemented 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 196