src/gui/text/qfontdatabase_mac.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <private/qt_mac_p.h>
       
    43 #include "qfontengine_p.h"
       
    44 #include <qfile.h>
       
    45 #include <qabstractfileengine.h>
       
    46 #include <stdlib.h>
       
    47 #include <qendian.h>
       
    48 
       
    49 QT_BEGIN_NAMESPACE
       
    50 
       
    51 int qt_mac_pixelsize(const QFontDef &def, int dpi); //qfont_mac.cpp
       
    52 int qt_mac_pointsize(const QFontDef &def, int dpi); //qfont_mac.cpp
       
    53 
       
    54 #ifndef QT_MAC_USE_COCOA
       
    55 static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont)
       
    56 {
       
    57     ByteCount length = 0;
       
    58     if (ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, 0, 0, &length) != noErr)
       
    59         return;
       
    60     QVarLengthArray<uchar> os2Table(length);
       
    61     if (length < 86
       
    62         || ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, length, os2Table.data(), &length) != noErr)
       
    63         return;
       
    64 
       
    65     // See also qfontdatabase_win.cpp, offsets taken from OS/2 table in the TrueType spec
       
    66     quint32 unicodeRange[4] = {
       
    67         qFromBigEndian<quint32>(os2Table.data() + 42),
       
    68         qFromBigEndian<quint32>(os2Table.data() + 46),
       
    69         qFromBigEndian<quint32>(os2Table.data() + 50),
       
    70         qFromBigEndian<quint32>(os2Table.data() + 54)
       
    71     };
       
    72     quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78), qFromBigEndian<quint32>(os2Table.data() + 82) };
       
    73     QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
       
    74 #if 0
       
    75     QCFString name;
       
    76     ATSFontGetName(atsFont, kATSOptionFlagsDefault, &name);
       
    77     qDebug() << systems.count() << "writing systems for" << QString(name);
       
    78 qDebug() << "first char" << hex << unicodeRange[0];
       
    79     for (int i = 0; i < systems.count(); ++i)
       
    80         qDebug() << QFontDatabase::writingSystemName(systems.at(i));
       
    81 #endif
       
    82     for (int i = 0; i < systems.count(); ++i)
       
    83         family->writingSystems[systems.at(i)] = QtFontFamily::Supported;
       
    84 }
       
    85 #endif
       
    86 
       
    87 static void initializeDb()
       
    88 {
       
    89     QFontDatabasePrivate *db = privateDb();
       
    90     if(!db || db->count)
       
    91         return;
       
    92 
       
    93 #if defined(QT_MAC_USE_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
       
    94 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
       
    95     QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
       
    96     if(!collection)
       
    97         return;
       
    98     QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
       
    99     if(!fonts)
       
   100         return;
       
   101     QString foundry_name = "CoreText";
       
   102     const int numFonts = CFArrayGetCount(fonts);
       
   103     for(int i = 0; i < numFonts; ++i) {
       
   104         CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
       
   105 
       
   106         QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
       
   107         QtFontFamily *family = db->family(family_name, true);
       
   108         for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws)
       
   109             family->writingSystems[ws] = QtFontFamily::Supported;
       
   110         QtFontFoundry *foundry = family->foundry(foundry_name, true);
       
   111 
       
   112         QtFontStyle::Key styleKey;
       
   113         if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
       
   114             if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
       
   115                 Q_ASSERT(CFNumberIsFloatType(weight));
       
   116                 double d;
       
   117                 if(CFNumberGetValue(weight, kCFNumberDoubleType, &d)) {
       
   118                     //qDebug() << "BOLD" << (QString)family_name << d;
       
   119                     styleKey.weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
       
   120                 }
       
   121             }
       
   122             if(CFNumberRef italic = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
       
   123                 Q_ASSERT(CFNumberIsFloatType(italic));
       
   124                 double d;
       
   125                 if(CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
       
   126                     //qDebug() << "ITALIC" << (QString)family_name << d;
       
   127                     if (d > 0.0)
       
   128                         styleKey.style = QFont::StyleItalic;
       
   129                 }
       
   130             }
       
   131         }
       
   132 
       
   133         QtFontStyle *style = foundry->style(styleKey, true);
       
   134         style->smoothScalable = true;
       
   135         if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
       
   136             //qDebug() << "WHEE";
       
   137             int pixel_size=0;
       
   138             if(CFNumberIsFloatType(size)) {
       
   139                 double d;
       
   140                 CFNumberGetValue(size, kCFNumberDoubleType, &d);
       
   141                 pixel_size = d;
       
   142             } else {
       
   143                 CFNumberGetValue(size, kCFNumberIntType, &pixel_size);
       
   144             }
       
   145             //qDebug() << "SIZE" << (QString)family_name << pixel_size;
       
   146             if(pixel_size)
       
   147                 style->pixelSize(pixel_size, true);
       
   148         } else {
       
   149             //qDebug() << "WTF?";
       
   150         }
       
   151     }
       
   152 } else 
       
   153 #endif
       
   154     {
       
   155 #ifndef QT_MAC_USE_COCOA
       
   156         FMFontIterator it;
       
   157         if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) {
       
   158             while (true) {
       
   159                 FMFont fmFont;
       
   160                 if (FMGetNextFont(&it, &fmFont) != noErr)
       
   161                     break;
       
   162 
       
   163                 FMFontFamily fmFamily;
       
   164                 FMFontStyle fmStyle;
       
   165                 QString familyName;
       
   166 
       
   167                 QtFontStyle::Key styleKey;
       
   168 
       
   169                 ATSFontRef atsFont = FMGetATSFontRefFromFont(fmFont);
       
   170 
       
   171                 if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) {
       
   172                     { //sanity check the font, and see if we can use it at all! --Sam
       
   173                         ATSUFontID fontID;
       
   174                         if(ATSUFONDtoFontID(fmFamily, 0, &fontID) != noErr)
       
   175                             continue;
       
   176                     }
       
   177 
       
   178                     if (fmStyle & ::italic)
       
   179                         styleKey.style = QFont::StyleItalic;
       
   180                     if (fmStyle & ::bold)
       
   181                         styleKey.weight = QFont::Bold;
       
   182 
       
   183                     ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily);
       
   184                     QCFString cfFamilyName;;
       
   185                     ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName);
       
   186                     familyName = cfFamilyName;
       
   187                 } else {
       
   188                     QCFString cfFontName;
       
   189                     ATSFontGetName(atsFont, kATSOptionFlagsDefault, &cfFontName);
       
   190                     familyName = cfFontName;
       
   191                     quint16 macStyle = 0;
       
   192                     {
       
   193                         uchar data[4];
       
   194                         ByteCount len = 4;
       
   195                         if (ATSFontGetTable(atsFont, MAKE_TAG('h', 'e', 'a', 'd'), 44, 4, &data, &len) == noErr)
       
   196                             macStyle = qFromBigEndian<quint16>(data);
       
   197                     }
       
   198                     if (macStyle & 1)
       
   199                         styleKey.weight = QFont::Bold;
       
   200                     if (macStyle & 2)
       
   201                         styleKey.style = QFont::StyleItalic;
       
   202                 }
       
   203 
       
   204                 QtFontFamily *family = db->family(familyName, true);
       
   205                 QtFontFoundry *foundry = family->foundry(QString(), true);
       
   206                 QtFontStyle *style = foundry->style(styleKey, true);
       
   207                 style->pixelSize(0, true);
       
   208                 style->smoothScalable = true;
       
   209 
       
   210                 initWritingSystems(family, atsFont);
       
   211             }
       
   212             FMDisposeFontIterator(&it);
       
   213         }
       
   214 #endif
       
   215     }
       
   216 
       
   217 }
       
   218 
       
   219 static inline void load(const QString & = QString(), int = -1)
       
   220 {
       
   221     initializeDb();
       
   222 }
       
   223 
       
   224 static const char *styleHint(const QFontDef &request)
       
   225 {
       
   226     const char *stylehint = 0;
       
   227     switch (request.styleHint) {
       
   228     case QFont::SansSerif:
       
   229         stylehint = "Arial";
       
   230         break;
       
   231     case QFont::Serif:
       
   232         stylehint = "Times New Roman";
       
   233         break;
       
   234     case QFont::TypeWriter:
       
   235         stylehint = "Courier New";
       
   236         break;
       
   237     default:
       
   238         if (request.fixedPitch)
       
   239             stylehint = "Courier New";
       
   240         break;
       
   241     }
       
   242     return stylehint;
       
   243 }
       
   244 
       
   245 void QFontDatabase::load(const QFontPrivate *d, int script)
       
   246 {
       
   247     // sanity checks
       
   248     if(!qApp)
       
   249         qWarning("QFont: Must construct a QApplication before a QFont");
       
   250 
       
   251     Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
       
   252     Q_UNUSED(script);
       
   253 
       
   254     QFontDef req = d->request;
       
   255     req.pixelSize = qt_mac_pixelsize(req, d->dpi);
       
   256 
       
   257     // set the point size to 0 to get better caching
       
   258     req.pointSize = 0;
       
   259     QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen);
       
   260 
       
   261     if(!(d->engineData = QFontCache::instance()->findEngineData(key))) {
       
   262         d->engineData = new QFontEngineData;
       
   263         QFontCache::instance()->insertEngineData(key, d->engineData);
       
   264     } else {
       
   265         d->engineData->ref.ref();
       
   266     }
       
   267     if(d->engineData->engine) // already loaded
       
   268         return;
       
   269 
       
   270     // set it to the actual pointsize, so QFontInfo will do the right thing
       
   271     req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi));
       
   272 
       
   273     QFontEngine *e = QFontCache::instance()->findEngine(key);
       
   274     if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
       
   275         e = new QTestFontEngine(req.pixelSize);
       
   276         e->fontDef = req;
       
   277     }
       
   278 
       
   279     if(e) {
       
   280         e->ref.ref();
       
   281         d->engineData->engine = e;
       
   282         return; // the font info and fontdef should already be filled
       
   283     }
       
   284 
       
   285     //find the font
       
   286     QStringList family_list = familyList(req);
       
   287 
       
   288     const char *stylehint = styleHint(req);
       
   289     if (stylehint)
       
   290         family_list << QLatin1String(stylehint);
       
   291 
       
   292     // add QFont::defaultFamily() to the list, for compatibility with
       
   293     // previous versions
       
   294     family_list << QApplication::font().defaultFamily();
       
   295 
       
   296     ATSFontFamilyRef familyRef = 0;
       
   297     ATSFontRef fontRef = 0;
       
   298 
       
   299     QMutexLocker locker(fontDatabaseMutex());
       
   300     QFontDatabasePrivate *db = privateDb();
       
   301     if (!db->count)
       
   302         initializeDb();
       
   303     for(int i = 0; i < family_list.size(); ++i) {
       
   304         for (int k = 0; k < db->count; ++k) {
       
   305             if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
       
   306                 QByteArray family_name = db->families[k]->name.toUtf8();
       
   307                 familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
       
   308                 if (familyRef) {
       
   309                     fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
       
   310                     goto FamilyFound;
       
   311                 } else {
       
   312 #if defined(QT_MAC_USE_COCOA)
       
   313                     // ATS and CT disagrees on what the family name should be,
       
   314                     // use CT to look up the font if ATS fails.
       
   315                     QCFString familyName = QString::fromAscii(family_name);
       
   316                     QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL);
       
   317                     QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef);
       
   318                     QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute);
       
   319 
       
   320                     familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault);
       
   321                     if (familyRef) {
       
   322                         fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault);
       
   323                         goto FamilyFound;
       
   324                     }
       
   325 #endif
       
   326                 }
       
   327             }
       
   328         }
       
   329     }
       
   330 FamilyFound:
       
   331     //fill in the engine's font definition
       
   332     QFontDef fontDef = d->request; //copy..
       
   333     if(fontDef.pointSize < 0)
       
   334 	fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
       
   335     else
       
   336 	fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
       
   337 #if 0
       
   338     ItemCount name_count;
       
   339     if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) {
       
   340         ItemCount actualName_size;
       
   341         if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) {
       
   342             QByteArray actualName(actualName_size);
       
   343             if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size)
       
   344                 fontDef.family = QString::fromUtf8(actualName);
       
   345         }
       
   346     }
       
   347 #else
       
   348     {
       
   349         QCFString actualName;
       
   350         if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
       
   351             fontDef.family = actualName;
       
   352     }
       
   353 #endif
       
   354 
       
   355 #ifdef QT_MAC_USE_COCOA
       
   356     QFontEngine *engine = new QCoreTextFontEngineMulti(familyRef, fontRef, fontDef, d->kerning);
       
   357 #elif 1
       
   358     QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
       
   359 #else
       
   360     ATSFontFamilyRef atsFamily = familyRef;
       
   361     ATSFontFamilyRef atsFontRef = fontRef;
       
   362 
       
   363     FMFont fontID;
       
   364     FMFontFamily fmFamily;
       
   365     FMFontStyle fntStyle = 0;
       
   366     fmFamily = FMGetFontFamilyFromATSFontFamilyRef(atsFamily);
       
   367     if (fmFamily == kInvalidFontFamily) {
       
   368         // Use the ATSFont then...
       
   369         fontID = FMGetFontFromATSFontRef(atsFontRef);
       
   370     } else {
       
   371         if (fontDef.weight >= QFont::Bold)
       
   372             fntStyle |= ::bold;
       
   373         if (fontDef.style != QFont::StyleNormal)
       
   374             fntStyle |= ::italic;
       
   375 
       
   376         FMFontStyle intrinsicStyle;
       
   377         FMFont fnt = 0;
       
   378         if (FMGetFontFromFontFamilyInstance(fmFamily, fntStyle, &fnt, &intrinsicStyle) == noErr)
       
   379            fontID = FMGetATSFontRefFromFont(fnt);
       
   380     }
       
   381 
       
   382     OSStatus status;
       
   383 
       
   384     const int maxAttributeCount = 5;
       
   385     ATSUAttributeTag tags[maxAttributeCount + 1];
       
   386     ByteCount sizes[maxAttributeCount + 1];
       
   387     ATSUAttributeValuePtr values[maxAttributeCount + 1];
       
   388     int attributeCount = 0;
       
   389 
       
   390     Fixed size = FixRatio(fontDef.pixelSize, 1);
       
   391     tags[attributeCount] = kATSUSizeTag;
       
   392     sizes[attributeCount] = sizeof(size);
       
   393     values[attributeCount] = &size;
       
   394     ++attributeCount;
       
   395 
       
   396     tags[attributeCount] = kATSUFontTag;
       
   397     sizes[attributeCount] = sizeof(fontID);
       
   398     values[attributeCount] = &fontID;
       
   399     ++attributeCount;
       
   400 
       
   401     CGAffineTransform transform = CGAffineTransformIdentity;
       
   402     if (fontDef.stretch != 100) {
       
   403         transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
       
   404         tags[attributeCount] = kATSUFontMatrixTag;
       
   405         sizes[attributeCount] = sizeof(transform);
       
   406         values[attributeCount] = &transform;
       
   407         ++attributeCount;
       
   408     }
       
   409 
       
   410     ATSUStyle style;
       
   411     status = ATSUCreateStyle(&style);
       
   412     Q_ASSERT(status == noErr);
       
   413 
       
   414     Q_ASSERT(attributeCount < maxAttributeCount + 1);
       
   415     status = ATSUSetAttributes(style, attributeCount, tags, sizes, values);
       
   416     Q_ASSERT(status == noErr);
       
   417 
       
   418     QFontEngine *engine = new QFontEngineMac(style, fontID, fontDef, /*multiEngine*/ 0);
       
   419     ATSUDisposeStyle(style);
       
   420 #endif
       
   421     d->engineData->engine = engine;
       
   422     engine->ref.ref(); //a ref for the engineData->engine
       
   423     QFontCache::instance()->insertEngine(key, engine);
       
   424 }
       
   425 
       
   426 static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
       
   427 {
       
   428     ATSFontContainerRef handle;
       
   429     OSStatus e  = noErr;
       
   430 
       
   431     if(fnt->data.isEmpty()) {
       
   432 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
       
   433         if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
       
   434                 extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
       
   435                 FSRef ref;
       
   436                 if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
       
   437                     return;
       
   438 
       
   439                 ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
       
   440         } else 
       
   441 #endif
       
   442         {
       
   443 #ifndef Q_WS_MAC64
       
   444                 extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
       
   445                 FSSpec spec;
       
   446                 if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
       
   447                     return;
       
   448 
       
   449                 e = ATSFontActivateFromFileSpecification(&spec, kATSFontContextLocal, kATSFontFormatUnspecified,
       
   450                                                    0, kATSOptionFlagsDefault, &handle);
       
   451 #endif
       
   452         }
       
   453     } else {
       
   454         e = ATSFontActivateFromMemory((void *)fnt->data.constData(), fnt->data.size(), kATSFontContextLocal,
       
   455                                            kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
       
   456 
       
   457         fnt->data = QByteArray();
       
   458     }
       
   459 
       
   460     if(e != noErr)
       
   461         return;
       
   462 
       
   463     ItemCount fontCount = 0;
       
   464     e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, 0, 0, &fontCount);
       
   465     if(e != noErr)
       
   466         return;
       
   467 
       
   468     QVarLengthArray<ATSFontRef> containedFonts(fontCount);
       
   469     e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
       
   470     if(e != noErr)
       
   471         return;
       
   472 
       
   473     fnt->families.clear();
       
   474 #if defined(QT_MAC_USE_COCOA)
       
   475     // Make sure that the family name set on the font matches what
       
   476     // kCTFontFamilyNameAttribute returns in initializeDb().
       
   477     // So far the best solution seems find the installed font
       
   478     // using CoreText and get the family name from it.
       
   479     // (ATSFontFamilyGetName appears to be the correct API, but also
       
   480     // returns the font display name.)
       
   481     for(int i = 0; i < containedFonts.size(); ++i) {
       
   482         QCFString fontPostScriptName;
       
   483         ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
       
   484         QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
       
   485         QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
       
   486         fnt->families.append(familyName);
       
   487     }
       
   488 #else
       
   489     for(int i = 0; i < containedFonts.size(); ++i) {
       
   490         QCFString family;
       
   491         ATSFontGetName(containedFonts[i], kATSOptionFlagsDefault, &family);
       
   492         fnt->families.append(family);
       
   493     }
       
   494 #endif
       
   495 
       
   496     fnt->handle = handle;
       
   497 }
       
   498 
       
   499 bool QFontDatabase::removeApplicationFont(int handle)
       
   500 {
       
   501     QMutexLocker locker(fontDatabaseMutex());
       
   502 
       
   503     QFontDatabasePrivate *db = privateDb();
       
   504     if(handle < 0 || handle >= db->applicationFonts.count())
       
   505         return false;
       
   506 
       
   507     OSStatus e = ATSFontDeactivate(db->applicationFonts.at(handle).handle,
       
   508                                    /*iRefCon=*/0, kATSOptionFlagsDefault);
       
   509     if(e != noErr)
       
   510         return false;
       
   511 
       
   512     db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
       
   513 
       
   514     db->invalidate();
       
   515     return true;
       
   516 }
       
   517 
       
   518 bool QFontDatabase::removeAllApplicationFonts()
       
   519 {
       
   520     QMutexLocker locker(fontDatabaseMutex());
       
   521 
       
   522     QFontDatabasePrivate *db = privateDb();
       
   523     for(int i = 0; i < db->applicationFonts.count(); ++i) {
       
   524         if(!removeApplicationFont(i))
       
   525             return false;
       
   526     }
       
   527     return true;
       
   528 }
       
   529 
       
   530 bool QFontDatabase::supportsThreadedFontRendering()
       
   531 {
       
   532     return true;
       
   533 }
       
   534 
       
   535 QT_END_NAMESPACE