static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
    ATSFontContainerRef handle;
    OSStatus e;

    if(fnt->data.isEmpty()) {
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
        extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
        FSRef ref;
        if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
            return;

        ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
} else 
#endif
{
        extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
        FSSpec spec;
        if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
            return;

        e = ATSFontActivateFromFileSpecification(&spec, kATSFontContextLocal, kATSFontFormatUnspecified,
                                           0, kATSOptionFlagsDefault, &handle);
}
    } else {
        e = ATSFontActivateFromMemory((void *)fnt->data.constData(), fnt->data.size(), kATSFontContextLocal,
                                           kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);

        fnt->data = QByteArray();
    }

    if(e != noErr)
        return;

    ItemCount fontCount = 0;
    e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, 0, 0, &fontCount);
    if(e != noErr)
        return;

    QVarLengthArray<ATSFontRef> containedFonts(fontCount);
    e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
    if(e != noErr)
        return;

    fnt->families.clear();
    for(int i = 0; i < containedFonts.size(); ++i) {
        QCFString family;
        ATSFontGetName(containedFonts[i], kATSOptionFlagsDefault, &family);
        fnt->families.append(family);
    }

    fnt->handle = handle;
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

    ATSFontContainerRef containerRef = 0;
    ATSFontRef fontRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
    
    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
#ifndef BUILDING_ON_TIGER
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
#endif
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)

    return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef());
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

    // Use ATS to activate the font.
    ATSFontContainerRef containerRef = 0;

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontRef fontRef = 0;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    CGFontRef cgFontRef = CGFontCreateWithPlatformFont(&fontRef);
#ifndef BUILDING_ON_TIGER
    // Workaround for <rdar://problem/5675504>.
    if (!CGFontGetNumberOfGlyphs(cgFontRef)) {
        CFRelease(cgFontRef);
        cgFontRef = 0;
    }
#endif
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }

    return new FontCustomPlatformData(containerRef, fontRef, cgFontRef);
}
Exemple #4
0
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
    ATSFontContainerRef handle;
    OSStatus e  = noErr;

    if(fnt->data.isEmpty()) {
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
                extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
                FSRef ref;
                if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
                    return;

                ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);
        } else 
#endif
        {
#ifndef Q_WS_MAC64
                extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
                FSSpec spec;
                if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
                    return;

                e = ATSFontActivateFromFileSpecification(&spec, kATSFontContextLocal, kATSFontFormatUnspecified,
                                                   0, kATSOptionFlagsDefault, &handle);
#endif
        }
    } else {
        e = ATSFontActivateFromMemory((void *)fnt->data.constData(), fnt->data.size(), kATSFontContextLocal,
                                           kATSFontFormatUnspecified, 0, kATSOptionFlagsDefault, &handle);

        fnt->data = QByteArray();
    }

    if(e != noErr)
        return;

    ItemCount fontCount = 0;
    e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, 0, 0, &fontCount);
    if(e != noErr)
        return;

    QVarLengthArray<ATSFontRef> containedFonts(fontCount);
    e = ATSFontFindFromContainer(handle, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
    if(e != noErr)
        return;

    fnt->families.clear();
#if defined(QT_MAC_USE_COCOA)
    // Make sure that the family name set on the font matches what
    // kCTFontFamilyNameAttribute returns in initializeDb().
    // So far the best solution seems find the installed font
    // using CoreText and get the family name from it.
    // (ATSFontFamilyGetName appears to be the correct API, but also
    // returns the font display name.)
    for(int i = 0; i < containedFonts.size(); ++i) {
        QCFString fontPostScriptName;
        ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
        QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
        QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
        fnt->families.append(familyName);
    }
#else
    for(int i = 0; i < containedFonts.size(); ++i) {
        QCFString family;
        ATSFontGetName(containedFonts[i], kATSOptionFlagsDefault, &family);
        fnt->families.append(family);
    }
#endif

    fnt->handle = handle;
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

#if USE(OPENTYPE_SANITIZER)
    OpenTypeSanitizer sanitizer(buffer);
    RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
    if (!transcodeBuffer)
        return 0; // validation failed.
    buffer = transcodeBuffer.get();
#else
    RefPtr<SharedBuffer> sfntBuffer;
    if (isWOFF(buffer)) {
        Vector<char> sfnt;
        if (!convertWOFFToSfnt(buffer, sfnt))
            return 0;

        sfntBuffer = SharedBuffer::adoptVector(sfnt);
        buffer = sfntBuffer.get();
    }
#endif

    ATSFontContainerRef containerRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#ifndef BUILDING_ON_LEOPARD
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));

    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontRef fontRef = 0;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_LEOPARD)

    FontCustomPlatformData* fontCustomPlatformData = new FontCustomPlatformData(containerRef, cgFontRef.releaseRef());
#if USE(SKIA_ON_MAC_CHROMIUM)
    RemoteFontStream* stream = new RemoteFontStream(buffer);
    fontCustomPlatformData->m_typeface = SkTypeface::CreateFromStream(stream);
    stream->unref();
#endif
    return fontCustomPlatformData;
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
    ASSERT_ARG(buffer, buffer);

#if ENABLE(OPENTYPE_SANITIZER)
    OpenTypeSanitizer sanitizer(buffer);
    RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
    if (!transcodeBuffer)
        return 0; // validation failed.
    buffer = transcodeBuffer.get();
#endif

    ATSFontContainerRef containerRef = 0;
    ATSFontRef fontRef = 0;

    RetainPtr<CGFontRef> cgFontRef;

#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
    
    cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
    if (!cgFontRef)
        return 0;
#else
    // Use ATS to activate the font.

    // The value "3" means that the font is private and can't be seen by anyone else.
    ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
    if (!containerRef)
        return 0;
    ItemCount fontCount;
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount);
    
    // We just support the first font in the list.
    if (fontCount == 0) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
    if (!fontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
    
    cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
#ifndef BUILDING_ON_TIGER
    // Workaround for <rdar://problem/5675504>.
    if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
        cgFontRef = 0;
#endif
	
#if PLATFORM(APOLLO)
	// On Leopard the CGFontGetNumberOfGlyphs call is necessary to reject invalid fonts
	// On Snow Leopard this happens at ATSFontActivateFromMemory
	if (isOsLeopardOrGreater()) {
		static _CGFontGetNumberOfGlyphsFunc CGFontGetNumberOfGlyphsFunc = getCGFontGetNumberOfGlyphsFunc();
		
		if (CGFontGetNumberOfGlyphsFunc && cgFontRef && !CGFontGetNumberOfGlyphsFunc(cgFontRef.get())) {
			cgFontRef = 0;
		}
	}
#endif
	
    if (!cgFontRef) {
        ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
        return 0;
    }
#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)

    return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef());
}