FontCacheAndroid.cpp revision cbcc214ef5f642d9b14ee5a542cc573441e6fb43
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"
37cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner#include <wtf/text/CString.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic const char* getFallbackFontName(const FontDescription& fontDescription)
42cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{
43cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    switch (fontDescription.genericFamily()) {
44cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::StandardFamily:
45cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::SerifFamily:
46cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "serif";
47cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::SansSerifFamily:
48cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "sans-serif";
49cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::MonospaceFamily:
50cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "monospace";
51cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::CursiveFamily:
52cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "cursive";
53cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::FantasyFamily:
54cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "fantasy";
55cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::NoFamily:
56cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    default:
57cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        return "";
58cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    }
59cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner}
60cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
61cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic bool isFallbackFamily(String family)
62cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{
63cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    return family.startsWith("-webkit-")
64cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "serif")
65cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "sans-serif")
66cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "sans")
67cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "monospace")
68cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "cursive")
69cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        || equalIgnoringCase(family, "fantasy");
70cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner}
71cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
72cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brennerstatic char* AtomicStringToUTF8String(const AtomicString& utf16)
73cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner{
74cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    SkASSERT(sizeof(uint16_t) == sizeof(utf16.characters()[0]));
75cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    const uint16_t* uni = (uint16_t*)utf16.characters();
76cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
77cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    size_t bytes = SkUTF16_ToUTF8(uni, utf16.length(), 0);
78cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    char* utf8 = (char*)sk_malloc_throw(bytes + 1);
79cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
80cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    (void)SkUTF16_ToUTF8(uni, utf16.length(), utf8);
81cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    utf8[bytes] = 0;
82cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    return utf8;
83cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner}
84cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
85cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::platformInit()
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // since all of our fonts logically map to the fallback, we can always claim
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that each font supports all characters.
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return font.primaryFont();
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
97477d5d728b7ab5d2a4fbefc981a5b5d41e15f187Steve BlockSimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
102cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell BrennerSimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description)
1037f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner{
104cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    static const AtomicString sansStr("sans-serif");
105cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    static const AtomicString serifStr("serif");
106cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    static const AtomicString monospaceStr("monospace");
107cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
108cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    FontPlatformData* fontPlatformData = 0;
109cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    switch (description.genericFamily()) {
110cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::SerifFamily:
111cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        fontPlatformData = getCachedFontPlatformData(description, serifStr);
112cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        break;
113cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::MonospaceFamily:
114cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        fontPlatformData = getCachedFontPlatformData(description, monospaceStr);
115cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        break;
116cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    case FontDescription::SansSerifFamily:
117cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    default:
118cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        fontPlatformData = getCachedFontPlatformData(description, sansStr);
119cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        break;
120cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    }
1217f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner
122cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    ASSERT(fontPlatformData);
123cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    return getCachedFontData(fontPlatformData);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
128cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    char* storage = 0;
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char* name = 0;
130cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    FontPlatformData* result = 0;
1317f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner
132cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    if (family.length()) {
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        storage = AtomicStringToUTF8String(family);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        name = storage;
135cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    } else
136cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        name = getFallbackFontName(fontDescription);
1377f3023a5515317c8d9ed577bbc141f3fefa64fadRussell Brenner
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int style = SkTypeface::kNormal;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fontDescription.weight() >= FontWeightBold)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        style |= SkTypeface::kBold;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fontDescription.italic())
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        style |= SkTypeface::kItalic;
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
144cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // CreateFromName always returns a typeface, falling back to a default font
145cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // if the one requested is not found. Calling Equal() with a null pointer
146cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // serves to compare the returned font against the default, with the caveat
147cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // that the default is always of normal style. If we detect the default, we
148cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // ignore it and allow WebCore to give us the next font on the CSS fallback
149cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // list. The only exception is if the family name is a commonly used generic
150cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // family, as when called by getSimilarFontPlatformData() and
151cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // getLastResortFallbackFont(). In this case, the default font is an
152cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    // acceptable result.
153cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
154cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
155cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
156cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    if (!SkTypeface::Equal(tf, 0) || isFallbackFamily(family.string())) {
157cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        // We had to use normal styling to see if this was a default font. If
158cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        // we need bold or italic, replace with the corrected typeface.
159cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        if (style != SkTypeface::kNormal) {
160cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner            tf->unref();
161cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner            tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style);
162cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        }
163cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner
164cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner        result = new FontPlatformData(tf, fontDescription.computedSize(),
165cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner                            (style & SkTypeface::kBold) && !tf->isBold(),
166cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner                            (style & SkTypeface::kItalic) && !tf->isItalic());
167cbcc214ef5f642d9b14ee5a542cc573441e6fb43Russell Brenner    }
168fd0bf63b4addb1bcb90de078bbd4700e2545a69fRussell Brenner
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    tf->unref();
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sk_free(storage);
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // new as of SVN change 36269, Sept 8, 2008
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Don't understand this yet, but it seems safe to leave unimplemented
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
181