18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
25f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
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:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "config.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "FontCache.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "Font.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "SimpleFontData.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "FontPlatformData.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebCoreSystemInterface.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebFontCache.h"
388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#import <AppKit/AppKit.h>
398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#import <wtf/StdLibExtras.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef BUILDING_ON_TIGER
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef int NSInteger;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic void fontCacheRegisteredFontsChangedNotificationCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void *, CFDictionaryRef)
495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT_UNUSED(observer, observer == fontCache());
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT_UNUSED(name, CFEqual(name, kCTFontManagerRegisteredFontsChangedNotification));
525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    fontCache()->invalidate();
535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void fontCacheATSNotificationCallback(ATSFontNotificationInfoRef, void*)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    fontCache()->invalidate();
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::platformInit()
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wkSetUpFontCache();
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, fontCacheRegisteredFontsChangedNotificationCallback, kCTFontManagerRegisteredFontsChangedNotification, 0, CFNotificationSuspensionBehaviorDeliverImmediately);
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // kCTFontManagerRegisteredFontsChangedNotification does not exist on Leopard and earlier.
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Passing kATSFontNotifyOptionReceiveWhileSuspended may be an overkill and does not seem to work anyway.
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ATSFontNotificationSubscribe(fontCacheATSNotificationCallback, kATSFontNotifyOptionReceiveWhileSuspended, 0, 0);
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int toAppKitFontWeight(FontWeight fontWeight)
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static int appKitFontWeights[] = {
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        2,  // FontWeight100
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        3,  // FontWeight200
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        4,  // FontWeight300
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        5,  // FontWeight400
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        6,  // FontWeight500
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        8,  // FontWeight600
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        9,  // FontWeight700
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        10, // FontWeight800
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        12, // FontWeight900
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return appKitFontWeights[fontWeight];
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight)
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return appKitFontWeight >= 7;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const FontPlatformData& platformData = font.fontDataAt(0)->fontDataForCharacter(characters[0])->platformData();
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFont *nsFont = platformData.font();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(characters) length:length freeWhenDone:NO];
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFont *substituteFont = wkGetFontInLanguageForRange(nsFont, string, NSMakeRange(0, length));
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [string release];
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!substituteFont && length == 1)
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        substituteFont = wkGetFontInLanguageForCharacter(nsFont, characters[0]);
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!substituteFont)
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Use the family name from the AppKit-supplied substitute font, requesting the
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // traits, weight, and size we want. One way this does better than the original
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // AppKit request is that it takes synthetic bold and oblique into account.
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // But it does create the possibility that we could end up with a font that
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // doesn't actually cover the characters we need.
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontManager *fontManager = [NSFontManager sharedFontManager];
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontTraitMask traits;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSInteger weight;
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGFloat size;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (nsFont) {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        traits = [fontManager traitsOfFont:nsFont];
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (platformData.m_syntheticBold)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            traits |= NSBoldFontMask;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (platformData.m_syntheticOblique)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            traits |= NSFontItalicTrait;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        weight = [fontManager weightOfFont:nsFont];
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size = [nsFont pointSize];
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For custom fonts nsFont is nil.
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        traits = font.italic() ? NSFontItalicTrait : 0;
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        weight = toAppKitFontWeight(font.weight());
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size = font.pixelSize();
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (NSFont *bestVariation = [fontManager fontWithFamily:[substituteFont familyName] traits:traits weight:weight size:size])
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        substituteFont = bestVariation;
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    substituteFont = font.fontDescription().usePrinterFont() ? [substituteFont printerFont] : [substituteFont screenFont];
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontTraitMask substituteFontTraits = [fontManager traitsOfFont:substituteFont];
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSInteger substituteFontWeight = [fontManager weightOfFont:substituteFont];
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    FontPlatformData alternateFont(substituteFont, platformData.size(),
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        !font.isPlatformFont() && isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(substituteFontWeight),
145e14391e94c850b8bd03680c23b38978db68687a8John Reck        !font.isPlatformFont() && (traits & NSFontItalicTrait) && !(substituteFontTraits & NSFontItalicTrait),
146e14391e94c850b8bd03680c23b38978db68687a8John Reck        platformData.m_orientation);
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getCachedFontData(&alternateFont);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockSimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Attempt to find an appropriate font using a match based on
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the presence of keywords in the the requested names.  For example, we'll
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // match any name that contains "Arabic" to Geeza Pro.
1558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    SimpleFontData* simpleFontData = 0;
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const FontFamily* currFamily = &font.fontDescription().family();
1578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    while (currFamily && !simpleFontData) {
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (currFamily->family().length()) {
159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            static String* matchWords[3] = { new String("Arabic"), new String("Pashto"), new String("Urdu") };
160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            DEFINE_STATIC_LOCAL(AtomicString, geezaStr, ("Geeza Pro"));
1618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            for (int j = 0; j < 3 && !simpleFontData; ++j)
162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (currFamily->family().contains(*matchWords[j], false))
1638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                    simpleFontData = getCachedFontData(font.fontDescription(), geezaStr);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currFamily = currFamily->next();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return simpleFontData;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockSimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(AtomicString, timesStr, ("Times"));
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Would be even better to somehow get the user's default font here.  For now we'll pick
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the default that the user would get without changing any prefs.
1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    SimpleFontData* simpleFontData = getCachedFontData(fontDescription, timesStr);
1788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (simpleFontData)
1798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return simpleFontData;
1808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    // The Times fallback will almost always work, but in the highly unusual case where
1828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    // the user doesn't have it, we fall back on Lucida Grande because that's
1838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    // guaranteed to be there, according to Nathan Taylor. This is good enough
1848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    // to avoid a crash at least.
1858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    DEFINE_STATIC_LOCAL(AtomicString, lucidaGrandeStr, ("Lucida Grande"));
1868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return getCachedFontData(fontDescription, lucidaGrandeStr);
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [WebFontCache getTraits:traitsMasks inFamily:familyName];
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontTraitMask traits = fontDescription.italic() ? NSFontItalicTrait : 0;
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSInteger weight = toAppKitFontWeight(fontDescription.weight());
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float size = fontDescription.computedPixelSize();
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFont *nsFont = [WebFontCache fontWithFamily:family traits:traits weight:weight size:size];
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!nsFont)
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontManager *fontManager = [NSFontManager sharedFontManager];
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSFontTraitMask actualTraits = 0;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fontDescription.italic())
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        actualTraits = [fontManager traitsOfFont:nsFont];
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSInteger actualWeight = [fontManager weightOfFont:nsFont];
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NSFont *platformFont = fontDescription.usePrinterFont() ? [nsFont printerFont] : [nsFont screenFont];
2118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight);
2128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block    return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.textOrientation(), fontDescription.widthVariant());
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
218