Home | History | Annotate | Download | only in android
      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